@graph8/sdk 0.13.1 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.d.ts CHANGED
@@ -1552,6 +1552,8 @@ declare const createInboxClient: (apiKey: string, apiUrl?: string) => {
1552
1552
  };
1553
1553
 
1554
1554
  interface Deal {
1555
+ /** Canonical CRM revision returned by a conditional update. */
1556
+ revision?: number | null;
1555
1557
  id: string | null;
1556
1558
  name: string | null;
1557
1559
  description: string | null;
@@ -1616,6 +1618,8 @@ interface DealCreateParams {
1616
1618
  allow_duplicate?: boolean;
1617
1619
  }
1618
1620
  interface DealUpdateParams {
1621
+ /** Require this current CRM revision; a stale edit returns HTTP 409. */
1622
+ expected_revision?: number;
1619
1623
  name?: string;
1620
1624
  description?: string;
1621
1625
  amount?: number;
@@ -1741,6 +1745,7 @@ declare const createDealsClient: (apiKey: string, apiUrl?: string) => {
1741
1745
  }>;
1742
1746
  };
1743
1747
 
1748
+ type CustomObjectIcon = "box" | "briefcase" | "building" | "calendar" | "flag" | "folder" | "globe" | "heart" | "layers" | "package" | "target" | "users";
1744
1749
  /** A custom object type in your workspace — a record type you define. */
1745
1750
  interface CustomObject {
1746
1751
  /** Stable API slug, e.g. `invoices`. */
@@ -1750,6 +1755,28 @@ interface CustomObject {
1750
1755
  /** True for object types graph8 ships; system objects cannot be deleted. */
1751
1756
  is_system: boolean;
1752
1757
  is_archived: boolean;
1758
+ /** Presentation settings may be absent on older servers. */
1759
+ description?: string | null;
1760
+ icon?: string | null;
1761
+ display_attribute_slug?: string | null;
1762
+ }
1763
+ /** Native schema creation requires objects:manage and current Admin access. */
1764
+ interface CreateCustomObject {
1765
+ slug: string;
1766
+ singular_noun: string;
1767
+ plural_noun: string;
1768
+ description?: string | null;
1769
+ icon?: CustomObjectIcon | null;
1770
+ }
1771
+ /** Omitted labels/state are preserved. The API slug is immutable. */
1772
+ interface UpdateCustomObject {
1773
+ singular_noun?: string;
1774
+ plural_noun?: string;
1775
+ is_archived?: boolean;
1776
+ /** Omit to preserve; null clears the setting. */
1777
+ description?: string | null;
1778
+ icon?: CustomObjectIcon | null;
1779
+ display_attribute_slug?: string | null;
1753
1780
  }
1754
1781
  /**
1755
1782
  * One attribute on a custom object, and the rules its values must satisfy.
@@ -1762,6 +1789,15 @@ interface CustomObject {
1762
1789
  */
1763
1790
  interface CustomObjectAttribute {
1764
1791
  slug: string;
1792
+ /** Customer-facing label. Display metadata is absent on older servers. */
1793
+ title?: string;
1794
+ description?: string | null;
1795
+ /** Display order; ties are ordered by slug. */
1796
+ sort_order?: number;
1797
+ /** Protected system field rather than a customer-defined field. */
1798
+ is_system?: boolean;
1799
+ /** Archive state; absent on older servers. */
1800
+ is_archived?: boolean;
1765
1801
  attribute_type: string;
1766
1802
  is_required: boolean;
1767
1803
  /** No two ACTIVE records may hold the same value. A collision returns 409. */
@@ -1774,6 +1810,24 @@ interface CustomObjectAttribute {
1774
1810
  /** Type-specific configuration, e.g. the allowed options for a `select`. */
1775
1811
  config: Record<string, unknown>;
1776
1812
  }
1813
+ /** Schema creation requires objects:manage and current Admin access. */
1814
+ interface CreateCustomObjectAttribute {
1815
+ slug: string;
1816
+ title: string;
1817
+ attribute_type: "text" | "number" | "currency" | "date" | "timestamp" | "checkbox" | "select" | "status" | "email_address" | "phone_number" | "domain" | "location" | "personal_name" | "record_reference" | "rating" | "actor_reference";
1818
+ description?: string | null;
1819
+ is_required?: boolean;
1820
+ is_unique?: boolean;
1821
+ is_multiselect?: boolean;
1822
+ is_default_value_enabled?: boolean;
1823
+ default_value?: unknown;
1824
+ config?: Record<string, unknown>;
1825
+ sort_order?: number;
1826
+ }
1827
+ /** Omitted fields are preserved; explicit null can clear the configured default. */
1828
+ type UpdateCustomObjectAttribute = Partial<Omit<CreateCustomObjectAttribute, "slug" | "attribute_type">> & {
1829
+ is_archived?: boolean;
1830
+ };
1777
1831
  /** One record, with its currently active attribute values. */
1778
1832
  interface CustomObjectRecord {
1779
1833
  id: string;
@@ -1804,6 +1858,29 @@ interface CustomObjectHistory {
1804
1858
  record_id: string;
1805
1859
  entries: CustomObjectHistoryEntry[];
1806
1860
  }
1861
+ interface CustomObjectMutation {
1862
+ id: string;
1863
+ action: "created" | "updated" | "archived" | "restored";
1864
+ occurred_at: string;
1865
+ revision: number;
1866
+ actor_id: string | null;
1867
+ actor_type: "user" | "api" | "app" | "integration" | "system";
1868
+ source: string;
1869
+ app_id: string | null;
1870
+ changes: Record<string, {
1871
+ before_present: boolean;
1872
+ before: unknown;
1873
+ after_present: boolean;
1874
+ after: unknown;
1875
+ }>;
1876
+ was_archived: boolean;
1877
+ is_archived: boolean;
1878
+ }
1879
+ interface CustomObjectMutations {
1880
+ record_id: string;
1881
+ entries: CustomObjectMutation[];
1882
+ next_cursor: string | null;
1883
+ }
1807
1884
  interface ListRecordsParams {
1808
1885
  page?: number;
1809
1886
  /** 1-200, default 50. */
@@ -1868,16 +1945,33 @@ interface ObjectPagination {
1868
1945
  */
1869
1946
  declare const createObjectsClient: (apiKey: string, apiUrl?: string) => {
1870
1947
  /** List the custom object types in your workspace. */
1871
- list(): Promise<{
1948
+ list(params?: {
1949
+ include_archived?: boolean;
1950
+ }): Promise<{
1872
1951
  data: CustomObject[];
1873
1952
  }>;
1953
+ /** Create a native custom object. Requires objects:manage and Admin access. */
1954
+ create(input: CreateCustomObject): Promise<CustomObject>;
1955
+ /** Rename, archive or restore an object while preserving its slug and data. */
1956
+ update(objectSlug: string, input: UpdateCustomObject): Promise<CustomObject>;
1957
+ /** Archive the object without deleting records; restore with update({ is_archived: false }). */
1958
+ archive(objectSlug: string): Promise<CustomObject>;
1874
1959
  /** Fetch one object type by slug. */
1875
1960
  get(objectSlug: string): Promise<CustomObject>;
1876
1961
  /** The object's attributes — the schema its records must satisfy. */
1877
- listAttributes(objectSlug: string): Promise<{
1962
+ listAttributes(objectSlug: string, params?: {
1963
+ include_archived?: boolean;
1964
+ }): Promise<{
1878
1965
  data: CustomObjectAttribute[];
1879
1966
  }>;
1880
- /** Paginated records with their current values. Archived records are excluded. */
1967
+ /** Create a field using the same schema rules as the customer UI. */
1968
+ createAttribute(objectSlug: string, input: CreateCustomObjectAttribute): Promise<CustomObjectAttribute>;
1969
+ /** Edit or restore a field; its type and slug are immutable. */
1970
+ updateAttribute(objectSlug: string, attributeSlug: string, input: UpdateCustomObjectAttribute): Promise<CustomObjectAttribute>;
1971
+ /** Archive without deleting values; restore with updateAttribute({ is_archived: false }). */
1972
+ archiveAttribute(objectSlug: string, attributeSlug: string): Promise<CustomObjectAttribute>;
1973
+ /** Paginated custom records or canonical deals with current values and revisions.
1974
+ * Deal totals and related references respect current record access. */
1881
1975
  listRecords(objectSlug: string, params?: ListRecordsParams): Promise<{
1882
1976
  data: CustomObjectRecord[];
1883
1977
  pagination?: ObjectPagination;
@@ -1888,18 +1982,28 @@ declare const createObjectsClient: (apiKey: string, apiUrl?: string) => {
1888
1982
  * unique attribute is a 409.
1889
1983
  */
1890
1984
  createRecord(objectSlug: string, values: Record<string, unknown>): Promise<CustomObjectRecord>;
1891
- /** Fetch one record with its currently active values. */
1985
+ /** Match a unique single-value key, creating or updating while preserving omitted fields. */
1986
+ upsertRecord(objectSlug: string, matchingAttribute: string, values: Record<string, unknown>, options?: {
1987
+ expectedRevision?: number;
1988
+ }): Promise<CustomObjectRecord>;
1989
+ /** Fetch one custom record, canonical contact/company, or deal by its stable graph8 ID.
1990
+ * Deals retain their UUIDs and expose company, primary-contact and contact_ids references only
1991
+ * when permitted. Generic deal mutations are not yet supported.
1992
+ */
1892
1993
  getRecord(objectSlug: string, recordId: string): Promise<CustomObjectRecord>;
1893
1994
  /**
1894
1995
  * Update a record. PARTIAL: only the attributes you send are touched, so
1895
1996
  * required attributes you omit are left alone rather than reported missing.
1896
1997
  * Sending an explicit `null` CLEARS that attribute.
1897
1998
  *
1898
- * Values are versioned rather than overwritten, so the previous value stays
1899
- * readable through `history`.
1999
+ * Custom values retain generations through `history`. Canonical contacts and
2000
+ * companies require expectedRevision from a fresh read and expose recorded
2001
+ * mutations through `changes`. They do not yet support appendValues/removeValues.
1900
2002
  */
1901
2003
  updateRecord(objectSlug: string, recordId: string, values: Record<string, unknown>, options?: {
1902
2004
  expectedRevision?: number;
2005
+ appendValues?: Record<string, unknown[]>;
2006
+ removeValues?: Record<string, unknown[]>;
1903
2007
  }): Promise<CustomObjectRecord>;
1904
2008
  /**
1905
2009
  * Archive a record. It leaves listings, stays readable by id, and keeps its
@@ -1913,6 +2017,280 @@ declare const createObjectsClient: (apiKey: string, apiUrl?: string) => {
1913
2017
  * null is the value currently in force.
1914
2018
  */
1915
2019
  history(objectSlug: string, recordId: string, limit?: number): Promise<CustomObjectHistory>;
2020
+ /** Recorded custom-record or canonical contact/company mutations. Pass next_cursor to continue.
2021
+ * Canonical history respects current access/privacy; archived records and older
2022
+ * unrecorded writes are not reconstructed. Store unavailability returns 503.
2023
+ */
2024
+ changes(objectSlug: string, recordId: string, options?: {
2025
+ limit?: number;
2026
+ cursor?: string;
2027
+ }): Promise<CustomObjectMutations>;
2028
+ };
2029
+
2030
+ /**
2031
+ * Hosted app platform — deployments, domains, secrets, source and logs (M9 J14).
2032
+ *
2033
+ * WHAT WAS MISSING. `apps.ts` covered creating an app and reading its installs,
2034
+ * usage and limit. Everything that actually SHIPS one -- binding a source,
2035
+ * queueing a deployment, promoting it, attaching a hostname, reading why a build
2036
+ * failed -- had no client at all. That is why the build portal is read-only: not
2037
+ * because the routes are absent, but because nothing typed reached them.
2038
+ *
2039
+ * EVERY RESPONSE ON THIS SURFACE IS WRAPPED as `{data, pagination}`, and
2040
+ * `pagination` is always null here -- none of these routes paginate. The helpers
2041
+ * below unwrap `data` so callers work with the record, except where the list IS
2042
+ * the answer.
2043
+ *
2044
+ * DELIBERATELY ABSENT, and each for a reason:
2045
+ *
2046
+ * * `POST /apps/{id}/deployments/{id}/status` -- authenticated with the build
2047
+ * CONTROLLER credential, not a builder's API key. An SDK method for it would
2048
+ * imply a customer can move their own deployment through the state machine.
2049
+ * * `GET /app-platform/tls-authorize` -- Caddy's on-demand-TLS ask hook. Public,
2050
+ * unauthenticated, returns a bare 200 or 404 with no body. It is edge
2051
+ * plumbing, not a customer API.
2052
+ */
2053
+ /** The six frozen values. Not widened to `string`: a client that switches on the
2054
+ * status should get a compile error when a new state is added. */
2055
+ type DeploymentStatus = "queued" | "building" | "promoting" | "deployed" | "failed" | "rolled_back";
2056
+ type DomainVerificationStatus = "pending" | "verified" | "failed" | "revoked";
2057
+ type SourceProvider = "github" | "gitlab" | "bitbucket";
2058
+ type SchemaVersionStatus = "draft" | "published" | "deprecated";
2059
+ interface Deployment {
2060
+ deployment_id: string;
2061
+ app_id: string;
2062
+ /** One of `DeploymentStatus`. Typed as the union, but the server sends a plain
2063
+ * string -- treat an unrecognised value as forward compatibility, not an error. */
2064
+ status: DeploymentStatus;
2065
+ source_ref: string | null;
2066
+ image_digest: string | null;
2067
+ schema_version_id: string | null;
2068
+ /** Sanitized at the WRITE. One line. The detail is in `logs()`. */
2069
+ last_error_sanitized: string | null;
2070
+ created_at: string | null;
2071
+ deployed_at: string | null;
2072
+ build_started_at: string | null;
2073
+ build_finished_at: string | null;
2074
+ /** Measured `building` -> `promoting`, NOT to `deployed`: `deployed` is reached
2075
+ * after traffic is taken, so measuring to it would count the promotion too. */
2076
+ build_seconds: number | null;
2077
+ }
2078
+ interface CreateDeploymentParams {
2079
+ /** A COMMIT-ish, never a branch name. A branch moves, so a deployment recorded
2080
+ * against one cannot answer "what is running right now" a week later. The
2081
+ * server enforces length only -- this convention is the caller's to keep. */
2082
+ source_ref: string;
2083
+ /** Pins the custom-object schema this build expects, so a rollback restores the
2084
+ * matching schema and not merely the matching image. */
2085
+ schema_version_id?: string;
2086
+ }
2087
+ interface AppDomain {
2088
+ domain_id: string;
2089
+ app_id: string;
2090
+ /** The canonical normalized form -- lowercased, trailing dot stripped, IDNA
2091
+ * encoded. NOT what you submitted. */
2092
+ hostname: string;
2093
+ status: DomainVerificationStatus;
2094
+ verification_token: string | null;
2095
+ created_at: string | null;
2096
+ verified_at: string | null;
2097
+ }
2098
+ interface DomainVerificationInstructions {
2099
+ domain: AppDomain;
2100
+ record_type: "TXT";
2101
+ record_name: string;
2102
+ record_value: string;
2103
+ }
2104
+ interface AppSecretMetadata {
2105
+ secret_key: string;
2106
+ /** A POINTER into your secret manager, never the secret. graph8 has no column
2107
+ * for a value and cannot grow one. */
2108
+ provider_ref: string | null;
2109
+ created_at: string | null;
2110
+ rotated_at: string | null;
2111
+ }
2112
+ interface AppSourceParams {
2113
+ repo_url: string;
2114
+ provider: SourceProvider;
2115
+ default_branch?: string;
2116
+ credential_ref?: string;
2117
+ }
2118
+ interface SchemaVersion {
2119
+ schema_version_id: string;
2120
+ app_id: string;
2121
+ version: number;
2122
+ digest: string;
2123
+ status: SchemaVersionStatus;
2124
+ manifest: Record<string, unknown>;
2125
+ created_at: string | null;
2126
+ published_at: string | null;
2127
+ deprecated_at: string | null;
2128
+ }
2129
+ interface ContainerLog {
2130
+ pod: string;
2131
+ container: string;
2132
+ /** `init` steps run to completion before the pod's containers start. A build is
2133
+ * four init steps (fetch, scan-source, build, scan-image) then one container
2134
+ * (push), so this is how you tell which step you are looking at. */
2135
+ kind: "init" | "container";
2136
+ text: string;
2137
+ /** The tail hit the per-container byte cap. Earlier output exists and was not
2138
+ * returned. */
2139
+ truncated: boolean;
2140
+ }
2141
+ interface AppLogs {
2142
+ app_id: string;
2143
+ /** Set for build logs; null for the running app's logs. */
2144
+ deployment_id: string | null;
2145
+ namespace: string;
2146
+ tail_lines: number;
2147
+ /**
2148
+ * Always true, and it means only that graph8's credential patterns ran.
2149
+ * It is NOT a claim the output is safe to publish: these are your own build and
2150
+ * application logs, and an application can print a secret in a shape no pattern
2151
+ * matches.
2152
+ */
2153
+ redacted: boolean;
2154
+ containers: ContainerLog[];
2155
+ }
2156
+ declare const createAppPlatformClient: (apiKey: string, apiUrl?: string) => {
2157
+ /**
2158
+ * Bind the repository an app builds from.
2159
+ *
2160
+ * `repo_url` must be fetchable -- `https://`, `ssh://` or `git@`, with no
2161
+ * whitespace. A `file://` or bare path is refused with 422, because a build
2162
+ * that can read the builder's filesystem is a build that can read ours.
2163
+ *
2164
+ * `credential_ref` is a POINTER into your secret manager, not a token.
2165
+ */
2166
+ setSource(appId: string, params: AppSourceParams): Promise<Record<string, unknown>>;
2167
+ /** Unbind the source. Returns the full app with every source field null. */
2168
+ clearSource(appId: string): Promise<Record<string, unknown>>;
2169
+ /** Every deployment for this app, newest first. Never 404s for an app with none. */
2170
+ listDeployments(appId: string): Promise<{
2171
+ data: Deployment[];
2172
+ }>;
2173
+ /**
2174
+ * Queue a deployment. Returns `201` with `status: "queued"` -- nothing builds
2175
+ * as a side effect of this call; the build controller picks it up.
2176
+ *
2177
+ * NOT idempotent: two identical calls create two deployments.
2178
+ */
2179
+ deploy(appId: string, params: CreateDeploymentParams): Promise<Deployment>;
2180
+ /** Fetch one deployment. The polling endpoint for a build loop. */
2181
+ getDeployment(appId: string, deploymentId: string): Promise<Deployment>;
2182
+ /**
2183
+ * The deployment currently serving traffic, or `null`.
2184
+ *
2185
+ * `null` is a real answer with a 200, not a 404: "this app has never shipped"
2186
+ * is information, while a 404 would read as "no such app".
2187
+ */
2188
+ activeDeployment(appId: string): Promise<Deployment | null>;
2189
+ /**
2190
+ * Promote a built deployment to serve traffic. Anything it displaces moves to
2191
+ * `rolled_back` in the same transaction, so there is never a moment with two
2192
+ * live deployments.
2193
+ *
2194
+ * `409` when the state machine forbids it -- a deployment cannot become
2195
+ * `deployed` without having been built, and a `failed` one cannot be revived.
2196
+ * A retry is a new deployment, not a resurrection.
2197
+ */
2198
+ promote(appId: string, deploymentId: string, imageDigest: string): Promise<Deployment>;
2199
+ /** Roll back a deployment that is currently serving. Only a `deployed` one may be. */
2200
+ rollback(appId: string, deploymentId: string): Promise<Deployment>;
2201
+ /**
2202
+ * Why a build failed. Returns every step of the build pod in the order
2203
+ * Kubernetes runs them; a step that has not started yet is omitted rather
2204
+ * than returned empty.
2205
+ *
2206
+ * An empty `containers` list is not an error -- build pods are reaped an hour
2207
+ * after they finish, so logs for an older deployment are genuinely gone.
2208
+ * `last_error_sanitized` on the deployment is what survives.
2209
+ *
2210
+ * `503` means graph8 could not reach the cluster, which is deliberately
2211
+ * different from an empty `200`: one means we could not look, the other means
2212
+ * your build produced no output.
2213
+ */
2214
+ deploymentLogs(appId: string, deploymentId: string, tailLines?: number): Promise<AppLogs>;
2215
+ /**
2216
+ * What the running app is printing. The app's own pods only -- the per-app
2217
+ * egress proxy shares the namespace and is deliberately excluded.
2218
+ *
2219
+ * Empty until a deployment reaches `deployed`.
2220
+ */
2221
+ logs(appId: string, tailLines?: number): Promise<AppLogs>;
2222
+ /** Every hostname claimed for this app, whatever its verification state. */
2223
+ listDomains(appId: string): Promise<{
2224
+ data: AppDomain[];
2225
+ }>;
2226
+ /**
2227
+ * Claim a hostname and get the TXT record that proves you own it.
2228
+ *
2229
+ * Returns `201`, and the domain is NESTED at `data.domain` -- this is the one
2230
+ * route on the surface whose payload is not the record itself. Hostnames are
2231
+ * globally unique, so a host another app holds is refused.
2232
+ */
2233
+ claimDomain(appId: string, hostname: string): Promise<DomainVerificationInstructions>;
2234
+ /**
2235
+ * Check DNS for the TXT record and advance the domain to `verified`.
2236
+ *
2237
+ * Idempotent: verifying an already-verified domain re-checks and stays
2238
+ * verified, so it is safe to re-run after a DNS change. Send no body -- the
2239
+ * record in DNS is the payload.
2240
+ */
2241
+ verifyDomain(appId: string, hostname: string): Promise<AppDomain>;
2242
+ /**
2243
+ * Release a claimed hostname.
2244
+ *
2245
+ * A HARD delete. Hostnames are globally unique, so a row left behind in any
2246
+ * status keeps the host burned for every other builder. Releasing one you
2247
+ * already released is a `404`, because after the first call the claim
2248
+ * genuinely does not exist.
2249
+ *
2250
+ * Returns the NORMALIZED hostname, which may differ from what you passed.
2251
+ */
2252
+ releaseDomain(appId: string, hostname: string): Promise<{
2253
+ hostname: string;
2254
+ released: boolean;
2255
+ }>;
2256
+ /**
2257
+ * Which secrets this app declares, and when each was last rotated.
2258
+ *
2259
+ * NEVER returns a value. graph8 stores a POINTER into your secret manager and
2260
+ * has no column for the secret itself.
2261
+ */
2262
+ listSecrets(appId: string): Promise<{
2263
+ data: AppSecretMetadata[];
2264
+ }>;
2265
+ /**
2266
+ * Declare a secret, or rotate the pointer to it.
2267
+ *
2268
+ * `providerRef` is a REFERENCE, and the server rejects anything that looks
2269
+ * like a credential -- a value starting `bearer `, `sk-`, `ghp_`, `xox` and
2270
+ * friends is a 422. That refusal is the feature: it catches the mistake of
2271
+ * pasting the secret where its address belongs.
2272
+ */
2273
+ putSecret(appId: string, secretKey: string, providerRef?: string): Promise<AppSecretMetadata>;
2274
+ /** Undeclare a secret. A key the app never declared is a 404, so a typo is
2275
+ * never reported as a successful removal. */
2276
+ deleteSecret(appId: string, secretKey: string): Promise<{
2277
+ secret_key: string;
2278
+ removed: boolean;
2279
+ }>;
2280
+ /**
2281
+ * Publish a custom-object schema version. Returns `201`.
2282
+ *
2283
+ * Takes only the `objects` list, not a whole `graph8.app.yaml`: the rest of
2284
+ * that file is app metadata the control plane already holds, and accepting it
2285
+ * here would create a second place for it to disagree.
2286
+ */
2287
+ publishSchemaVersion(appId: string, objects: unknown[]): Promise<{
2288
+ version: SchemaVersion;
2289
+ }>;
2290
+ /** Every schema version this app has published. Empty array, never 404. */
2291
+ listSchemaVersions(appId: string): Promise<{
2292
+ data: SchemaVersion[];
2293
+ }>;
1916
2294
  };
1917
2295
 
1918
2296
  /**
@@ -2515,7 +2893,7 @@ declare const createContactsClient: (apiKey: string, apiUrl?: string) => {
2515
2893
  * adds events. ``WebhookEvent`` also accepts any string so a newly-added
2516
2894
  * backend event never breaks a client that hasn't upgraded.
2517
2895
  */
2518
- declare const KNOWN_WEBHOOK_EVENTS: readonly ["campaign.created", "campaign.updated", "campaign.deleted", "campaign.launched", "campaign.paused", "campaign.completed", "campaign.status_changed", "campaign.content_ready", "document.generated", "document.failed", "intelligence.completed", "intelligence.failed", "company.enriched", "company_intelligence.completed", "audience.ready", "audience.failed", "sequence.draft_created", "sequence.started", "sequence.paused", "sequence.completed", "engagement.email_sent", "engagement.email_replied", "engagement.email_bounced", "engagement.email_skipped", "engagement.call_dispatched", "engagement.sms_sent", "engagement.sms_replied", "engagement.whatsapp_sent", "engagement.linkedin_connection_sent", "engagement.linkedin_message_sent", "engagement.linkedin_inmail_sent", "engagement.linkedin_reply_received", "engagement.linkedin_connection_accepted", "meeting.booked", "meeting.cancelled", "meeting.rescheduled"];
2896
+ declare const KNOWN_WEBHOOK_EVENTS: readonly ["campaign.created", "campaign.updated", "campaign.deleted", "campaign.launched", "campaign.paused", "campaign.completed", "campaign.status_changed", "campaign.content_ready", "document.generated", "document.failed", "intelligence.completed", "intelligence.failed", "company.enriched", "company_intelligence.completed", "audience.ready", "audience.failed", "sequence.draft_created", "sequence.started", "sequence.paused", "sequence.completed", "engagement.email_sent", "engagement.email_replied", "engagement.email_bounced", "engagement.email_skipped", "engagement.call_dispatched", "engagement.call_connected", "engagement.call_graded", "engagement.sms_sent", "engagement.sms_replied", "engagement.whatsapp_sent", "engagement.linkedin_connection_sent", "engagement.linkedin_message_sent", "engagement.linkedin_inmail_sent", "engagement.linkedin_reply_received", "engagement.linkedin_connection_accepted", "meeting.booked", "meeting.cancelled", "meeting.rescheduled", "deal.won", "crm.record.created", "crm.record.updated", "crm.record.archived", "crm.record.restored"];
2519
2897
  type WebhookEvent = (typeof KNOWN_WEBHOOK_EVENTS)[number] | (string & {});
2520
2898
  /** The decoded body graph8 delivers to a webhook endpoint. */
2521
2899
  interface WebhookEventPayload {
@@ -2523,7 +2901,7 @@ interface WebhookEventPayload {
2523
2901
  timestamp: string;
2524
2902
  data: Record<string, unknown>;
2525
2903
  org_id: string;
2526
- /** Stable per-delivery id (present once the backend adds it; for consumer dedup). */
2904
+ /** Stable event ID for consumer deduplication; delivery ID is in X-Studio-Delivery-Id. */
2527
2905
  id?: string;
2528
2906
  }
2529
2907
  interface ConstructEventOptions {
@@ -2542,7 +2920,7 @@ declare const createWebhooksClient: (_apiKey: string, apiUrl?: string) => {
2542
2920
  /** Base URL the webhook subscription API lives under. */
2543
2921
  baseUrl: string;
2544
2922
  /** Known event types (for autocomplete / validation). */
2545
- knownEvents: readonly ["campaign.created", "campaign.updated", "campaign.deleted", "campaign.launched", "campaign.paused", "campaign.completed", "campaign.status_changed", "campaign.content_ready", "document.generated", "document.failed", "intelligence.completed", "intelligence.failed", "company.enriched", "company_intelligence.completed", "audience.ready", "audience.failed", "sequence.draft_created", "sequence.started", "sequence.paused", "sequence.completed", "engagement.email_sent", "engagement.email_replied", "engagement.email_bounced", "engagement.email_skipped", "engagement.call_dispatched", "engagement.sms_sent", "engagement.sms_replied", "engagement.whatsapp_sent", "engagement.linkedin_connection_sent", "engagement.linkedin_message_sent", "engagement.linkedin_inmail_sent", "engagement.linkedin_reply_received", "engagement.linkedin_connection_accepted", "meeting.booked", "meeting.cancelled", "meeting.rescheduled"];
2923
+ knownEvents: readonly ["campaign.created", "campaign.updated", "campaign.deleted", "campaign.launched", "campaign.paused", "campaign.completed", "campaign.status_changed", "campaign.content_ready", "document.generated", "document.failed", "intelligence.completed", "intelligence.failed", "company.enriched", "company_intelligence.completed", "audience.ready", "audience.failed", "sequence.draft_created", "sequence.started", "sequence.paused", "sequence.completed", "engagement.email_sent", "engagement.email_replied", "engagement.email_bounced", "engagement.email_skipped", "engagement.call_dispatched", "engagement.call_connected", "engagement.call_graded", "engagement.sms_sent", "engagement.sms_replied", "engagement.whatsapp_sent", "engagement.linkedin_connection_sent", "engagement.linkedin_message_sent", "engagement.linkedin_inmail_sent", "engagement.linkedin_reply_received", "engagement.linkedin_connection_accepted", "meeting.booked", "meeting.cancelled", "meeting.rescheduled", "deal.won", "crm.record.created", "crm.record.updated", "crm.record.archived", "crm.record.restored"];
2546
2924
  /** Verify an incoming webhook's HMAC signature and return the parsed event. */
2547
2925
  constructEvent(payload: string, signature: string, timestamp: string | number, secret: string, opts?: ConstructEventOptions): WebhookEventPayload;
2548
2926
  };
@@ -3499,6 +3877,7 @@ declare const useG8: () => {
3499
3877
  _tasks: ReturnType<typeof createTasksClient> | null;
3500
3878
  _fields: ReturnType<typeof createFieldsClient> | null;
3501
3879
  _apps: ReturnType<typeof createAppsClient> | null;
3880
+ _appPlatform: ReturnType<typeof createAppPlatformClient> | null;
3502
3881
  _objects: ReturnType<typeof createObjectsClient> | null;
3503
3882
  _deals: ReturnType<typeof createDealsClient> | null;
3504
3883
  _inbox: ReturnType<typeof createInboxClient> | null;
@@ -3648,7 +4027,7 @@ declare const useG8: () => {
3648
4027
  };
3649
4028
  get webhooks(): {
3650
4029
  baseUrl: string;
3651
- knownEvents: readonly ["campaign.created", "campaign.updated", "campaign.deleted", "campaign.launched", "campaign.paused", "campaign.completed", "campaign.status_changed", "campaign.content_ready", "document.generated", "document.failed", "intelligence.completed", "intelligence.failed", "company.enriched", "company_intelligence.completed", "audience.ready", "audience.failed", "sequence.draft_created", "sequence.started", "sequence.paused", "sequence.completed", "engagement.email_sent", "engagement.email_replied", "engagement.email_bounced", "engagement.email_skipped", "engagement.call_dispatched", "engagement.sms_sent", "engagement.sms_replied", "engagement.whatsapp_sent", "engagement.linkedin_connection_sent", "engagement.linkedin_message_sent", "engagement.linkedin_inmail_sent", "engagement.linkedin_reply_received", "engagement.linkedin_connection_accepted", "meeting.booked", "meeting.cancelled", "meeting.rescheduled"];
4030
+ knownEvents: readonly ["campaign.created", "campaign.updated", "campaign.deleted", "campaign.launched", "campaign.paused", "campaign.completed", "campaign.status_changed", "campaign.content_ready", "document.generated", "document.failed", "intelligence.completed", "intelligence.failed", "company.enriched", "company_intelligence.completed", "audience.ready", "audience.failed", "sequence.draft_created", "sequence.started", "sequence.paused", "sequence.completed", "engagement.email_sent", "engagement.email_replied", "engagement.email_bounced", "engagement.email_skipped", "engagement.call_dispatched", "engagement.call_connected", "engagement.call_graded", "engagement.sms_sent", "engagement.sms_replied", "engagement.whatsapp_sent", "engagement.linkedin_connection_sent", "engagement.linkedin_message_sent", "engagement.linkedin_inmail_sent", "engagement.linkedin_reply_received", "engagement.linkedin_connection_accepted", "meeting.booked", "meeting.cancelled", "meeting.rescheduled", "deal.won", "crm.record.created", "crm.record.updated", "crm.record.archived", "crm.record.restored"];
3652
4031
  constructEvent(payload: string, signature: string, timestamp: string | number, secret: string, opts?: ConstructEventOptions): WebhookEventPayload;
3653
4032
  };
3654
4033
  get contacts(): {
@@ -3772,26 +4151,82 @@ declare const useG8: () => {
3772
4151
  usage(appId: string, period?: string): Promise<AppUsageSummary>;
3773
4152
  getLimit(appId: string): Promise<AppLimit | null>;
3774
4153
  };
4154
+ get appPlatform(): {
4155
+ setSource(appId: string, params: AppSourceParams): Promise<Record<string, unknown>>;
4156
+ clearSource(appId: string): Promise<Record<string, unknown>>;
4157
+ listDeployments(appId: string): Promise<{
4158
+ data: Deployment[];
4159
+ }>;
4160
+ deploy(appId: string, params: CreateDeploymentParams): Promise<Deployment>;
4161
+ getDeployment(appId: string, deploymentId: string): Promise<Deployment>;
4162
+ activeDeployment(appId: string): Promise<Deployment | null>;
4163
+ promote(appId: string, deploymentId: string, imageDigest: string): Promise<Deployment>;
4164
+ rollback(appId: string, deploymentId: string): Promise<Deployment>;
4165
+ deploymentLogs(appId: string, deploymentId: string, tailLines?: number): Promise<AppLogs>;
4166
+ logs(appId: string, tailLines?: number): Promise<AppLogs>;
4167
+ listDomains(appId: string): Promise<{
4168
+ data: AppDomain[];
4169
+ }>;
4170
+ claimDomain(appId: string, hostname: string): Promise<DomainVerificationInstructions>;
4171
+ verifyDomain(appId: string, hostname: string): Promise<AppDomain>;
4172
+ releaseDomain(appId: string, hostname: string): Promise<{
4173
+ hostname: string;
4174
+ released: boolean;
4175
+ }>;
4176
+ listSecrets(appId: string): Promise<{
4177
+ data: AppSecretMetadata[];
4178
+ }>;
4179
+ putSecret(appId: string, secretKey: string, providerRef?: string): Promise<AppSecretMetadata>;
4180
+ deleteSecret(appId: string, secretKey: string): Promise<{
4181
+ secret_key: string;
4182
+ removed: boolean;
4183
+ }>;
4184
+ publishSchemaVersion(appId: string, objects: unknown[]): Promise<{
4185
+ version: SchemaVersion;
4186
+ }>;
4187
+ listSchemaVersions(appId: string): Promise<{
4188
+ data: SchemaVersion[];
4189
+ }>;
4190
+ };
3775
4191
  get objects(): {
3776
- list(): Promise<{
4192
+ list(params?: {
4193
+ include_archived?: boolean;
4194
+ }): Promise<{
3777
4195
  data: CustomObject[];
3778
4196
  }>;
4197
+ create(input: CreateCustomObject): Promise<CustomObject>;
4198
+ update(objectSlug: string, input: UpdateCustomObject): Promise<CustomObject>;
4199
+ archive(objectSlug: string): Promise<CustomObject>;
3779
4200
  get(objectSlug: string): Promise<CustomObject>;
3780
- listAttributes(objectSlug: string): Promise<{
4201
+ listAttributes(objectSlug: string, params?: {
4202
+ include_archived?: boolean;
4203
+ }): Promise<{
3781
4204
  data: CustomObjectAttribute[];
3782
4205
  }>;
4206
+ createAttribute(objectSlug: string, input: CreateCustomObjectAttribute): Promise<CustomObjectAttribute>;
4207
+ updateAttribute(objectSlug: string, attributeSlug: string, input: UpdateCustomObjectAttribute): Promise<CustomObjectAttribute>;
4208
+ archiveAttribute(objectSlug: string, attributeSlug: string): Promise<CustomObjectAttribute>;
3783
4209
  listRecords(objectSlug: string, params?: ListRecordsParams): Promise<{
3784
4210
  data: CustomObjectRecord[];
3785
4211
  pagination?: ObjectPagination;
3786
4212
  }>;
3787
4213
  createRecord(objectSlug: string, values: Record<string, unknown>): Promise<CustomObjectRecord>;
4214
+ upsertRecord(objectSlug: string, matchingAttribute: string, values: Record<string, unknown>, options?: {
4215
+ expectedRevision?: number;
4216
+ }): Promise<CustomObjectRecord>;
3788
4217
  getRecord(objectSlug: string, recordId: string): Promise<CustomObjectRecord>;
3789
4218
  updateRecord(objectSlug: string, recordId: string, values: Record<string, unknown>, options?: {
3790
4219
  expectedRevision?: number;
4220
+ appendValues?: Record<string, unknown[]>;
4221
+ removeValues?: Record<string, unknown[]>;
3791
4222
  }): Promise<CustomObjectRecord>;
3792
4223
  archiveRecord(objectSlug: string, recordId: string): Promise<CustomObjectRecord>;
3793
4224
  restoreRecord(objectSlug: string, recordId: string): Promise<CustomObjectRecord>;
3794
4225
  history(objectSlug: string, recordId: string, limit?: number): Promise<CustomObjectHistory>;
4226
+ changes(objectSlug: string, recordId: string, options?: {
4227
+ limit?: number;
4228
+ cursor?: string;
4229
+ }): Promise<CustomObjectMutations>;
3795
4230
  };
3796
4231
  get deals(): {
3797
4232
  pipelines(): Promise<{