@graph8/sdk 0.13.0 → 0.14.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/README.md CHANGED
@@ -251,6 +251,28 @@ export const CTA = () => {
251
251
  | `g8.webhooks.constructEvent(body, sig, ts, secret, opts?)` | Verify a delivery's HMAC signature and return the parsed event (throws `WebhookSignatureError`) |
252
252
  | `g8.webhooks.knownEvents` | The known event-type catalog |
253
253
 
254
+ ## Native custom objects
255
+
256
+ Use an organization API key with explicit `objects:read` for schema/record/history
257
+ reads, `objects:write` for create/PATCH, and `objects:delete` for archive. Unscoped
258
+ keys receive 403. `objects:*` grants all three; grant only the operations the
259
+ integration needs.
260
+
261
+ ```typescript
262
+ import { g8 } from '@graph8/sdk';
263
+
264
+ g8.init({ apiKey: process.env.G8_API_KEY! });
265
+ const { data: objects } = await g8.objects.list();
266
+ const { data: attributes } = await g8.objects.listAttributes('invoices');
267
+ // Assumes this workspace defines an invoices object with a reference attribute.
268
+ const invoice = await g8.objects.createRecord('invoices', { reference: 'INV-1042' });
269
+ const history = await g8.objects.history('invoices', invoice.id);
270
+ ```
271
+
272
+ PATCH preserves omitted attributes. Enabled defaults apply only on create;
273
+ unknown fields return 422 and unique-value collisions return 409. Standard
274
+ contacts, companies, and deals continue using their existing SDK resources.
275
+
254
276
  ## App Platform
255
277
 
256
278
  Hosted apps do not carry a permanent org API key. Instead they **exchange** a
@@ -275,8 +297,8 @@ const appClient = createGraph8AppClient({
275
297
  });
276
298
 
277
299
  // Reach the existing resources with the app token via request():
278
- const { data: contacts } = await appClient.request<{ data: unknown[] }>(
279
- '/api/v1/contacts',
300
+ const { data: objects } = await appClient.request<{ data: unknown[] }>(
301
+ '/api/v1/app/objects',
280
302
  { query: { limit: 10 } },
281
303
  );
282
304
  ```
@@ -295,12 +317,12 @@ const service = createGraph8ServiceClient({
295
317
  scopes: ['objects:read', 'objects:write'],
296
318
  });
297
319
 
298
- const { data: rows } = await service.request<{ data: unknown[] }>('/api/v1/contacts');
320
+ const { data: objects } = await service.request<{ data: unknown[] }>('/api/v1/app/objects');
299
321
  ```
300
322
 
301
- > The typed `apps` (control-plane) and `objects` (custom-object CRUD) resource
302
- > modules are deferred until their backend routes ship (M6-3 / M6-5). Until then,
303
- > reach the Developer API through the token-bound `request()` shown above.
323
+ > App-token clients use `request()` for their consented app-owned objects.
324
+ > The `g8.objects` resource above uses an API key for native workspace objects;
325
+ > it does not substitute for app-token authorization.
304
326
 
305
327
  ## Auth Modes
306
328
 
@@ -315,3 +337,37 @@ Get your API key at [app.graph8.com/settings](https://app.graph8.com/settings) u
315
337
  ## License
316
338
 
317
339
  MIT
340
+
341
+
342
+ ### Conditional custom-record updates
343
+
344
+ Custom-record responses expose `revision`. Pass it when saving an interactive edit:
345
+
346
+ ```ts
347
+ import { g8 } from "@graph8/sdk";
348
+
349
+ g8.init({ apiKey: "YOUR_API_KEY" });
350
+ const projectId = "your-project-record-id";
351
+ const record = await g8.objects.getRecord("projects", projectId);
352
+ const updated = await g8.objects.updateRecord(
353
+ "projects", record.id, { name: "Updated project" },
354
+ { expectedRevision: record.revision },
355
+ );
356
+ ```
357
+
358
+ A stale revision returns HTTP 409 with code `revision_conflict`; reload the record
359
+ and reconcile the edit before retrying. Native and app APIs accept
360
+ `expected_revision` in the PATCH body, and the MCP update tool accepts the same
361
+ argument. Omitting it retains unconditional PATCH behavior. Older servers may
362
+ omit `revision`; deploy the revision-enabled backend before relying on this
363
+ precondition. This applies to custom-object records.
364
+
365
+
366
+ Restore a custom record with `g8.objects.restoreRecord(objectSlug, recordId)`.
367
+ The native API uses `POST /api/v1/objects/{objectSlug}/records/{recordId}/restore`;
368
+ MCP exposes `g8_object_record_restore`. Restoration preserves the original ID and
369
+ old history, validates the current schema and references, and returns 409 if a
370
+ unique value has been reused. Validation failures leave the record archived.
371
+ Ambiguous legacy history returns 422 with `archive_snapshot_unavailable` rather
372
+ than guessing its prior values. Repeating a successful restore adds no revision
373
+ or history entry.
package/dist/index.d.mts CHANGED
@@ -1765,6 +1765,10 @@ interface CustomObjectAttribute {
1765
1765
  /** No two ACTIVE records may hold the same value. A collision returns 409. */
1766
1766
  is_unique: boolean;
1767
1767
  is_multiselect: boolean;
1768
+ /** Apply a non-null default to omitted create fields, never PATCH. Absent on older servers. */
1769
+ is_default_value_enabled?: boolean;
1770
+ /** Configured default; validated like an explicit value when enabled. */
1771
+ default_value?: unknown;
1768
1772
  /** Type-specific configuration, e.g. the allowed options for a `select`. */
1769
1773
  config: Record<string, unknown>;
1770
1774
  }
@@ -1780,6 +1784,8 @@ interface CustomObjectRecord {
1780
1784
  */
1781
1785
  values: Record<string, unknown>;
1782
1786
  is_archived: boolean;
1787
+ /** Revision for conditional updates; absent on older servers. */
1788
+ revision?: number;
1783
1789
  created_at: string | null;
1784
1790
  updated_at: string | null;
1785
1791
  }
@@ -1824,10 +1830,7 @@ interface ObjectPagination {
1824
1830
  * Requires an API key (server-side). On the hardened HTTP core: throws a typed
1825
1831
  * `G8Error` on failure and retries transient errors.
1826
1832
  *
1827
- * PREVIEW AND GATED. Every endpoint returns 403 `app_not_enabled` until the
1828
- * custom-objects surface is switched on for the platform. It is off by default,
1829
- * so a call fails fast rather than returning an empty list that reads as "you
1830
- * have no objects".
1833
+ * Access requires an authenticated credential with the applicable object scope.
1831
1834
  *
1832
1835
  * HOW THIS DIFFERS FROM `g8.fields`. A FIELD adds a column to an existing
1833
1836
  * contact or company. A CUSTOM OBJECT is a whole new record type with its own
@@ -1840,10 +1843,16 @@ interface ObjectPagination {
1840
1843
  * lose your data, and the response lists every problem at once so a payload
1841
1844
  * with three mistakes takes one round trip to fix.
1842
1845
  * 2. `update` is a PARTIAL write. Attributes you omit are left alone; sending
1843
- * an explicit `null` CLEARS one. The two are deliberately different.
1846
+ * an explicit `null` clears an optional attribute. Required attributes
1847
+ * cannot be cleared with `null` or an empty multivalue list (422).
1844
1848
  * 3. `archive` does not destroy anything. The record leaves listings, stays
1845
1849
  * readable by id, and keeps its history.
1846
1850
  *
1851
+ * Record references must resolve to an active record of `config.target_object`
1852
+ * within the same organization and app. Unavailable targets return a 422 with
1853
+ * `invalid_reference` in the field error's `reason`, without disclosing whether
1854
+ * a target exists outside the caller's scope.
1855
+ *
1847
1856
  * Backed by:
1848
1857
  * GET /api/v1/objects
1849
1858
  * GET /api/v1/objects/{slug}
@@ -1887,12 +1896,16 @@ declare const createObjectsClient: (apiKey: string, apiUrl?: string) => {
1887
1896
  * Values are versioned rather than overwritten, so the previous value stays
1888
1897
  * readable through `history`.
1889
1898
  */
1890
- updateRecord(objectSlug: string, recordId: string, values: Record<string, unknown>): Promise<CustomObjectRecord>;
1899
+ updateRecord(objectSlug: string, recordId: string, values: Record<string, unknown>, options?: {
1900
+ expectedRevision?: number;
1901
+ }): Promise<CustomObjectRecord>;
1891
1902
  /**
1892
1903
  * Archive a record. It leaves listings, stays readable by id, and keeps its
1893
1904
  * history and associations. Nothing is destroyed.
1894
1905
  */
1895
1906
  archiveRecord(objectSlug: string, recordId: string): Promise<CustomObjectRecord>;
1907
+ /** Restore archived values under current constraints. Conflicts leave the record archived. */
1908
+ restoreRecord(objectSlug: string, recordId: string): Promise<CustomObjectRecord>;
1896
1909
  /**
1897
1910
  * A record's value timeline, newest first. An entry whose `active_until` is
1898
1911
  * null is the value currently in force.
@@ -1900,6 +1913,276 @@ declare const createObjectsClient: (apiKey: string, apiUrl?: string) => {
1900
1913
  history(objectSlug: string, recordId: string, limit?: number): Promise<CustomObjectHistory>;
1901
1914
  };
1902
1915
 
1916
+ /**
1917
+ * Hosted app platform — deployments, domains, secrets, source and logs (M9 J14).
1918
+ *
1919
+ * WHAT WAS MISSING. `apps.ts` covered creating an app and reading its installs,
1920
+ * usage and limit. Everything that actually SHIPS one -- binding a source,
1921
+ * queueing a deployment, promoting it, attaching a hostname, reading why a build
1922
+ * failed -- had no client at all. That is why the build portal is read-only: not
1923
+ * because the routes are absent, but because nothing typed reached them.
1924
+ *
1925
+ * EVERY RESPONSE ON THIS SURFACE IS WRAPPED as `{data, pagination}`, and
1926
+ * `pagination` is always null here -- none of these routes paginate. The helpers
1927
+ * below unwrap `data` so callers work with the record, except where the list IS
1928
+ * the answer.
1929
+ *
1930
+ * DELIBERATELY ABSENT, and each for a reason:
1931
+ *
1932
+ * * `POST /apps/{id}/deployments/{id}/status` -- authenticated with the build
1933
+ * CONTROLLER credential, not a builder's API key. An SDK method for it would
1934
+ * imply a customer can move their own deployment through the state machine.
1935
+ * * `GET /app-platform/tls-authorize` -- Caddy's on-demand-TLS ask hook. Public,
1936
+ * unauthenticated, returns a bare 200 or 404 with no body. It is edge
1937
+ * plumbing, not a customer API.
1938
+ */
1939
+ /** The six frozen values. Not widened to `string`: a client that switches on the
1940
+ * status should get a compile error when a new state is added. */
1941
+ type DeploymentStatus = "queued" | "building" | "promoting" | "deployed" | "failed" | "rolled_back";
1942
+ type DomainVerificationStatus = "pending" | "verified" | "failed" | "revoked";
1943
+ type SourceProvider = "github" | "gitlab" | "bitbucket";
1944
+ type SchemaVersionStatus = "draft" | "published" | "deprecated";
1945
+ interface Deployment {
1946
+ deployment_id: string;
1947
+ app_id: string;
1948
+ /** One of `DeploymentStatus`. Typed as the union, but the server sends a plain
1949
+ * string -- treat an unrecognised value as forward compatibility, not an error. */
1950
+ status: DeploymentStatus;
1951
+ source_ref: string | null;
1952
+ image_digest: string | null;
1953
+ schema_version_id: string | null;
1954
+ /** Sanitized at the WRITE. One line. The detail is in `logs()`. */
1955
+ last_error_sanitized: string | null;
1956
+ created_at: string | null;
1957
+ deployed_at: string | null;
1958
+ build_started_at: string | null;
1959
+ build_finished_at: string | null;
1960
+ /** Measured `building` -> `promoting`, NOT to `deployed`: `deployed` is reached
1961
+ * after traffic is taken, so measuring to it would count the promotion too. */
1962
+ build_seconds: number | null;
1963
+ }
1964
+ interface CreateDeploymentParams {
1965
+ /** A COMMIT-ish, never a branch name. A branch moves, so a deployment recorded
1966
+ * against one cannot answer "what is running right now" a week later. The
1967
+ * server enforces length only -- this convention is the caller's to keep. */
1968
+ source_ref: string;
1969
+ /** Pins the custom-object schema this build expects, so a rollback restores the
1970
+ * matching schema and not merely the matching image. */
1971
+ schema_version_id?: string;
1972
+ }
1973
+ interface AppDomain {
1974
+ domain_id: string;
1975
+ app_id: string;
1976
+ /** The canonical normalized form -- lowercased, trailing dot stripped, IDNA
1977
+ * encoded. NOT what you submitted. */
1978
+ hostname: string;
1979
+ status: DomainVerificationStatus;
1980
+ verification_token: string | null;
1981
+ created_at: string | null;
1982
+ verified_at: string | null;
1983
+ }
1984
+ interface DomainVerificationInstructions {
1985
+ domain: AppDomain;
1986
+ record_type: "TXT";
1987
+ record_name: string;
1988
+ record_value: string;
1989
+ }
1990
+ interface AppSecretMetadata {
1991
+ secret_key: string;
1992
+ /** A POINTER into your secret manager, never the secret. graph8 has no column
1993
+ * for a value and cannot grow one. */
1994
+ provider_ref: string | null;
1995
+ created_at: string | null;
1996
+ rotated_at: string | null;
1997
+ }
1998
+ interface AppSourceParams {
1999
+ repo_url: string;
2000
+ provider: SourceProvider;
2001
+ default_branch?: string;
2002
+ credential_ref?: string;
2003
+ }
2004
+ interface SchemaVersion {
2005
+ schema_version_id: string;
2006
+ app_id: string;
2007
+ version: number;
2008
+ digest: string;
2009
+ status: SchemaVersionStatus;
2010
+ manifest: Record<string, unknown>;
2011
+ created_at: string | null;
2012
+ published_at: string | null;
2013
+ deprecated_at: string | null;
2014
+ }
2015
+ interface ContainerLog {
2016
+ pod: string;
2017
+ container: string;
2018
+ /** `init` steps run to completion before the pod's containers start. A build is
2019
+ * four init steps (fetch, scan-source, build, scan-image) then one container
2020
+ * (push), so this is how you tell which step you are looking at. */
2021
+ kind: "init" | "container";
2022
+ text: string;
2023
+ /** The tail hit the per-container byte cap. Earlier output exists and was not
2024
+ * returned. */
2025
+ truncated: boolean;
2026
+ }
2027
+ interface AppLogs {
2028
+ app_id: string;
2029
+ /** Set for build logs; null for the running app's logs. */
2030
+ deployment_id: string | null;
2031
+ namespace: string;
2032
+ tail_lines: number;
2033
+ /**
2034
+ * Always true, and it means only that graph8's credential patterns ran.
2035
+ * It is NOT a claim the output is safe to publish: these are your own build and
2036
+ * application logs, and an application can print a secret in a shape no pattern
2037
+ * matches.
2038
+ */
2039
+ redacted: boolean;
2040
+ containers: ContainerLog[];
2041
+ }
2042
+ /** Lines per container. The server refuses anything outside 1-2000 with a 422
2043
+ * rather than clamping, so the bound is worth knowing before you send it. */
2044
+ declare const MIN_TAIL_LINES = 1;
2045
+ declare const MAX_TAIL_LINES = 2000;
2046
+ declare const createAppPlatformClient: (apiKey: string, apiUrl?: string) => {
2047
+ /**
2048
+ * Bind the repository an app builds from.
2049
+ *
2050
+ * `repo_url` must be fetchable -- `https://`, `ssh://` or `git@`, with no
2051
+ * whitespace. A `file://` or bare path is refused with 422, because a build
2052
+ * that can read the builder's filesystem is a build that can read ours.
2053
+ *
2054
+ * `credential_ref` is a POINTER into your secret manager, not a token.
2055
+ */
2056
+ setSource(appId: string, params: AppSourceParams): Promise<Record<string, unknown>>;
2057
+ /** Unbind the source. Returns the full app with every source field null. */
2058
+ clearSource(appId: string): Promise<Record<string, unknown>>;
2059
+ /** Every deployment for this app, newest first. Never 404s for an app with none. */
2060
+ listDeployments(appId: string): Promise<{
2061
+ data: Deployment[];
2062
+ }>;
2063
+ /**
2064
+ * Queue a deployment. Returns `201` with `status: "queued"` -- nothing builds
2065
+ * as a side effect of this call; the build controller picks it up.
2066
+ *
2067
+ * NOT idempotent: two identical calls create two deployments.
2068
+ */
2069
+ deploy(appId: string, params: CreateDeploymentParams): Promise<Deployment>;
2070
+ /** Fetch one deployment. The polling endpoint for a build loop. */
2071
+ getDeployment(appId: string, deploymentId: string): Promise<Deployment>;
2072
+ /**
2073
+ * The deployment currently serving traffic, or `null`.
2074
+ *
2075
+ * `null` is a real answer with a 200, not a 404: "this app has never shipped"
2076
+ * is information, while a 404 would read as "no such app".
2077
+ */
2078
+ activeDeployment(appId: string): Promise<Deployment | null>;
2079
+ /**
2080
+ * Promote a built deployment to serve traffic. Anything it displaces moves to
2081
+ * `rolled_back` in the same transaction, so there is never a moment with two
2082
+ * live deployments.
2083
+ *
2084
+ * `409` when the state machine forbids it -- a deployment cannot become
2085
+ * `deployed` without having been built, and a `failed` one cannot be revived.
2086
+ * A retry is a new deployment, not a resurrection.
2087
+ */
2088
+ promote(appId: string, deploymentId: string, imageDigest: string): Promise<Deployment>;
2089
+ /** Roll back a deployment that is currently serving. Only a `deployed` one may be. */
2090
+ rollback(appId: string, deploymentId: string): Promise<Deployment>;
2091
+ /**
2092
+ * Why a build failed. Returns every step of the build pod in the order
2093
+ * Kubernetes runs them; a step that has not started yet is omitted rather
2094
+ * than returned empty.
2095
+ *
2096
+ * An empty `containers` list is not an error -- build pods are reaped an hour
2097
+ * after they finish, so logs for an older deployment are genuinely gone.
2098
+ * `last_error_sanitized` on the deployment is what survives.
2099
+ *
2100
+ * `503` means graph8 could not reach the cluster, which is deliberately
2101
+ * different from an empty `200`: one means we could not look, the other means
2102
+ * your build produced no output.
2103
+ */
2104
+ deploymentLogs(appId: string, deploymentId: string, tailLines?: number): Promise<AppLogs>;
2105
+ /**
2106
+ * What the running app is printing. The app's own pods only -- the per-app
2107
+ * egress proxy shares the namespace and is deliberately excluded.
2108
+ *
2109
+ * Empty until a deployment reaches `deployed`.
2110
+ */
2111
+ logs(appId: string, tailLines?: number): Promise<AppLogs>;
2112
+ /** Every hostname claimed for this app, whatever its verification state. */
2113
+ listDomains(appId: string): Promise<{
2114
+ data: AppDomain[];
2115
+ }>;
2116
+ /**
2117
+ * Claim a hostname and get the TXT record that proves you own it.
2118
+ *
2119
+ * Returns `201`, and the domain is NESTED at `data.domain` -- this is the one
2120
+ * route on the surface whose payload is not the record itself. Hostnames are
2121
+ * globally unique, so a host another app holds is refused.
2122
+ */
2123
+ claimDomain(appId: string, hostname: string): Promise<DomainVerificationInstructions>;
2124
+ /**
2125
+ * Check DNS for the TXT record and advance the domain to `verified`.
2126
+ *
2127
+ * Idempotent: verifying an already-verified domain re-checks and stays
2128
+ * verified, so it is safe to re-run after a DNS change. Send no body -- the
2129
+ * record in DNS is the payload.
2130
+ */
2131
+ verifyDomain(appId: string, hostname: string): Promise<AppDomain>;
2132
+ /**
2133
+ * Release a claimed hostname.
2134
+ *
2135
+ * A HARD delete. Hostnames are globally unique, so a row left behind in any
2136
+ * status keeps the host burned for every other builder. Releasing one you
2137
+ * already released is a `404`, because after the first call the claim
2138
+ * genuinely does not exist.
2139
+ *
2140
+ * Returns the NORMALIZED hostname, which may differ from what you passed.
2141
+ */
2142
+ releaseDomain(appId: string, hostname: string): Promise<{
2143
+ hostname: string;
2144
+ released: boolean;
2145
+ }>;
2146
+ /**
2147
+ * Which secrets this app declares, and when each was last rotated.
2148
+ *
2149
+ * NEVER returns a value. graph8 stores a POINTER into your secret manager and
2150
+ * has no column for the secret itself.
2151
+ */
2152
+ listSecrets(appId: string): Promise<{
2153
+ data: AppSecretMetadata[];
2154
+ }>;
2155
+ /**
2156
+ * Declare a secret, or rotate the pointer to it.
2157
+ *
2158
+ * `providerRef` is a REFERENCE, and the server rejects anything that looks
2159
+ * like a credential -- a value starting `bearer `, `sk-`, `ghp_`, `xox` and
2160
+ * friends is a 422. That refusal is the feature: it catches the mistake of
2161
+ * pasting the secret where its address belongs.
2162
+ */
2163
+ putSecret(appId: string, secretKey: string, providerRef?: string): Promise<AppSecretMetadata>;
2164
+ /** Undeclare a secret. A key the app never declared is a 404, so a typo is
2165
+ * never reported as a successful removal. */
2166
+ deleteSecret(appId: string, secretKey: string): Promise<{
2167
+ secret_key: string;
2168
+ removed: boolean;
2169
+ }>;
2170
+ /**
2171
+ * Publish a custom-object schema version. Returns `201`.
2172
+ *
2173
+ * Takes only the `objects` list, not a whole `graph8.app.yaml`: the rest of
2174
+ * that file is app metadata the control plane already holds, and accepting it
2175
+ * here would create a second place for it to disagree.
2176
+ */
2177
+ publishSchemaVersion(appId: string, objects: unknown[]): Promise<{
2178
+ version: SchemaVersion;
2179
+ }>;
2180
+ /** Every schema version this app has published. Empty array, never 404. */
2181
+ listSchemaVersions(appId: string): Promise<{
2182
+ data: SchemaVersion[];
2183
+ }>;
2184
+ };
2185
+
1903
2186
  /**
1904
2187
  * App lifecycle. `draft` serves no traffic; `published` is live; `suspended` is a
1905
2188
  * platform action and cannot be set through this client; `archived` is retired.
@@ -3495,6 +3778,7 @@ declare class G8 {
3495
3778
  /** @internal */ _tasks: ReturnType<typeof createTasksClient> | null;
3496
3779
  /** @internal */ _fields: ReturnType<typeof createFieldsClient> | null;
3497
3780
  /** @internal */ _apps: ReturnType<typeof createAppsClient> | null;
3781
+ /** @internal */ _appPlatform: ReturnType<typeof createAppPlatformClient> | null;
3498
3782
  /** @internal */ _objects: ReturnType<typeof createObjectsClient> | null;
3499
3783
  /** @internal */ _deals: ReturnType<typeof createDealsClient> | null;
3500
3784
  /** @internal */ _inbox: ReturnType<typeof createInboxClient> | null;
@@ -3653,7 +3937,7 @@ declare class G8 {
3653
3937
  }>;
3654
3938
  listCallsForSdr(userEmail: string, extra?: {
3655
3939
  limit?: number;
3656
- date_from?: string;
3940
+ date_from? /** Audiences — sync audience lists to ad platforms (Meta, LinkedIn, Google, X) (requires API key). */: string;
3657
3941
  date_to?: string;
3658
3942
  }): Promise<{
3659
3943
  data: Array<Record<string, unknown>>;
@@ -3794,6 +4078,51 @@ declare class G8 {
3794
4078
  usage(appId: string, period?: string): Promise<AppUsageSummary>;
3795
4079
  getLimit(appId: string): Promise<AppLimit | null>;
3796
4080
  };
4081
+ /**
4082
+ * Ship a hosted app: bind a source, deploy, promote, attach a hostname, read
4083
+ * build logs (requires API key). PREVIEW.
4084
+ *
4085
+ * Separate from `apps` on purpose. `apps` is the app's IDENTITY -- create it,
4086
+ * see who installed it, what it cost. This is its LIFECYCLE, and the two have
4087
+ * different blast radii: a mistake here takes a customer's app down.
4088
+ */
4089
+ get appPlatform(): {
4090
+ setSource(appId: string, params: AppSourceParams): Promise<Record<string, unknown>>;
4091
+ clearSource(appId: string): Promise<Record<string, unknown>>;
4092
+ listDeployments(appId: string): Promise<{
4093
+ data: Deployment[];
4094
+ }>;
4095
+ deploy(appId: string, params: CreateDeploymentParams): Promise<Deployment>;
4096
+ getDeployment(appId: string, deploymentId: string): Promise<Deployment>;
4097
+ activeDeployment(appId: string): Promise<Deployment | null>;
4098
+ promote(appId: string, deploymentId: string, imageDigest: string): Promise<Deployment>;
4099
+ rollback(appId: string, deploymentId: string): Promise<Deployment>;
4100
+ deploymentLogs(appId: string, deploymentId: string, tailLines?: number): Promise<AppLogs>;
4101
+ logs(appId: string, tailLines?: number): Promise<AppLogs>;
4102
+ listDomains(appId: string): Promise<{
4103
+ data: AppDomain[];
4104
+ }>;
4105
+ claimDomain(appId: string, hostname: string): Promise<DomainVerificationInstructions>;
4106
+ verifyDomain(appId: string, hostname: string): Promise<AppDomain>;
4107
+ releaseDomain(appId: string, hostname: string): Promise<{
4108
+ hostname: string;
4109
+ released: boolean;
4110
+ }>;
4111
+ listSecrets(appId: string): Promise<{
4112
+ data: AppSecretMetadata[];
4113
+ }>;
4114
+ putSecret(appId: string, secretKey: string, providerRef?: string): Promise<AppSecretMetadata>;
4115
+ deleteSecret(appId: string, secretKey: string): Promise<{
4116
+ secret_key: string;
4117
+ removed: boolean;
4118
+ }>;
4119
+ publishSchemaVersion(appId: string, objects: unknown[]): Promise<{
4120
+ version: SchemaVersion;
4121
+ }>;
4122
+ listSchemaVersions(appId: string): Promise<{
4123
+ data: SchemaVersion[];
4124
+ }>;
4125
+ };
3797
4126
  /** Custom object types, their schema, and their records (requires API key). PREVIEW. */
3798
4127
  get objects(): {
3799
4128
  list(): Promise<{
@@ -3809,8 +4138,11 @@ declare class G8 {
3809
4138
  }>;
3810
4139
  createRecord(objectSlug: string, values: Record<string, unknown>): Promise<CustomObjectRecord>;
3811
4140
  getRecord(objectSlug: string, recordId: string): Promise<CustomObjectRecord>;
3812
- updateRecord(objectSlug: string, recordId: string, values: Record<string, unknown>): Promise<CustomObjectRecord>;
4141
+ updateRecord(objectSlug: string, recordId: string, values: Record<string, unknown>, options?: {
4142
+ expectedRevision?: number;
4143
+ }): Promise<CustomObjectRecord>;
3813
4144
  archiveRecord(objectSlug: string, recordId: string): Promise<CustomObjectRecord>;
4145
+ restoreRecord(objectSlug: string, recordId: string): Promise<CustomObjectRecord>;
3814
4146
  history(objectSlug: string, recordId: string, limit?: number): Promise<CustomObjectHistory>;
3815
4147
  };
3816
4148
  /** Deals and pipelines (requires API key). */
@@ -4108,7 +4440,8 @@ declare class G8 {
4108
4440
  }>;
4109
4441
  keywordContacts(keywordId: string, params?: {
4110
4442
  limit?: number;
4111
- date_from?: string;
4443
+ date_from
4444
+ /** @internal */ ? /** @internal */: string;
4112
4445
  date_to?: string;
4113
4446
  }): Promise<{
4114
4447
  data: IntentContact[];
@@ -4182,7 +4515,7 @@ declare class G8 {
4182
4515
  }>;
4183
4516
  researchReports(params?: {
4184
4517
  category?: string;
4185
- limit?: number;
4518
+ limit? /** @internal */: number;
4186
4519
  }): Promise<{
4187
4520
  data: ResearchReport[];
4188
4521
  }>;
@@ -4202,7 +4535,8 @@ declare class G8 {
4202
4535
  description?: string;
4203
4536
  firmographics?: Record<string, unknown>;
4204
4537
  tech_stack?: Record<string, unknown>;
4205
- buying_signals?: unknown[];
4538
+ buying_signals
4539
+ /** @internal */ ? /** @internal */: unknown[];
4206
4540
  estimated_market_size?: number;
4207
4541
  }): Promise<{
4208
4542
  data: ICP;
@@ -4218,7 +4552,10 @@ declare class G8 {
4218
4552
  why_target?: string;
4219
4553
  key_signals?: unknown[];
4220
4554
  expected_receptivity?: string;
4221
- campaign_approach?: string;
4555
+ campaign_approach? /**
4556
+ * Initialize the graph8 SDK. Must be called before any other method.
4557
+ * Safe to call on the server (SSR) - becomes a no-op for tracking.
4558
+ */: string;
4222
4559
  recommended_goal?: string;
4223
4560
  source?: string;
4224
4561
  }): Promise<{
@@ -4630,4 +4967,4 @@ interface Graph8ServiceClient {
4630
4967
  */
4631
4968
  declare function createGraph8ServiceClient(config: Graph8ServiceClientConfig): Graph8ServiceClient;
4632
4969
 
4633
- export { type AddToSequenceConfig, type AgencyClient, type AgencyInfo, type App, type AppCreateParams, type AppInstallation, type AppLimit, type AppRequest, type AppRequestOptions, type AppStatus, type AppTokenResponse, type AppUsageSummary, type AudienceSync, type AudienceSyncCreateParams, type AudienceSyncError, type AudienceSyncMode, type AudienceSyncPlatform, type AudienceSyncRun, type AudienceSyncUpdateParams, type Booking, type BookingRequest, type CalendarConfig, type CallGradingResult, type Campaign, type CampaignCreateConfig, type CampaignLaunchExecution, type CampaignLaunchResult, type ChatConfig, type Company, type CompanyColumn, type CompanyColumnCreateParams, type CompanyContact, type CompanyEnrichment, type CompanyListParams, type CompanyUpdateParams, type ConstructEventOptions, type Contact, type ContactColumn, type ContactColumnCreateParams, type ContactCreateParams, type ContactDeal, type ContactList, type ContactListParams, type ContactUpdateParams, type CopilotConfig, type CreatedField, type CustomObject, type CustomObjectAttribute, type CustomObjectHistory, type CustomObjectHistoryEntry, type CustomObjectRecord, DEFAULT_APP_API, type Deal, type DealCreateParams, type DealListParams, type DealUpdateParams, type DialerAgentSummary, type DialerAgentsListParams, type DialerAgentsListResult, type DialerNumberInfo, type DialerNumbersListResult, type DialerReportFilters, type DialerReportMetric, type DialerSessionCreateParams, type DialerSessionCreateResult, type DialerSessionResumeResult, type DialerSessionStatus, type DialerSessionStatusUpdateResult, type DialerSessionSummary, type DialerSessionsListParams, type DialerSessionsListResult, type DialerStatsParams, type DialerStatsResult, type EmailVerification, type EnrichLookupResult, type EvidenceKey, type Field, type FieldCreateParams, type FieldDeleteParams, type G8Config, G8Error, type G8PrivacyConfig, type GlobalContextDocument, type Graph8AppClient, type Graph8AppClientConfig, type Graph8ServiceClient, type Graph8ServiceClientConfig, type ICP, type IdentifyProperties, type InboxAssignResult, type InboxAssignee, type InboxChannel, type InboxContact, type InboxDraft, type InboxListParams, type InboxMessage, type InboxSendParams, type InboxSendResult, type InboxTag, type InboxTagResult, type InboxThread, type InstallStatus, type IntelligenceData, type IntentCompany, type IntentContact, type IntentKeyword, type IntentPage, type IntentSignals, type IntentStats, type IntentVisitor, KNOWN_WEBHOOK_EVENTS, type ListContact, type ListRecordsParams, type MarketplaceHiring, type MarketplaceOffer, type MarketplaceProfile, type MeetingAnalysis, type MeetingAttendee, type MeetingDetail, type MeetingListParams, type MeetingSummary, type MeetingTranscriptLine, type MissedCallback, type MissedCallbacksResult, type NodeTypeSchema, type Note, type ObjectPagination, type PaginatedResponse, type PaginationMeta$1 as PaginationMeta, type PersonEnrichment, type Persona, type Pipeline, type PipelineStage, type PipelineSuggestion, type QuotableProduct, type QuoteCreateParams, type QuoteDetail, type QuoteLineItem, type QuoteListParams, type QuoteSendParams, type QuoteSettings, type QuoteStatus, type QuoteSummary, type QuoteUpdateParams, type RequestOptions, type ResearchReport, type SearchCompanyItem, type SearchCondition, type SearchContactItem, type SearchFilter, type SearchOperator, type SearchParams, type SearchResults, type SearchSaveParams, type SearchSaveResult, type Sequence, type SequenceActionResult, type SequenceAnalytics, type SequenceChannelConfig, type SequenceContactItem, type SequenceContactsParams, type SequenceCreateParams, type SequenceCreateResult, type SequenceDetail, type SequenceKind, type SequenceListItem, type SequenceListParams, type SequencePreview, type SequencePreviewChannel, type SequencePreviewStep, type SequenceStepConfig, type SequenceStepInputType, type SequenceStepType, type SequenceStepUpdateParams, type SequenceUpdateParams, type SetFieldValueParams, type Skill, type SkillCreateAPIParams, type SkillCreateLLMParams, type SkillInputField, type SkillListParams, type SkillTemplate, type SkillType, type SkillUpdateAPIParams, type SkillUpdateLLMParams, type Snippet, type StageCreateParams, type StagePipeline, type StagePipelineCreateParams, type StagePipelineStage, type StagePipelineUpdateParams, type StageUpdateParams, type Task, type TaskCreateParams, type TaskListParams, type TaskUpdateParams, type TimeSlot, type TokenManager, type TrackProperties, type VisitorCompany, type VisitorScore, type VoicePagination, type WebhookEvent, type WebhookEventPayload, WebhookSignatureError, type Workflow, type WorkflowConfig, type WorkflowConnection, type WorkflowCreateParams, type WorkflowExecution, type WorkflowListParams, type WorkflowNode, type WorkflowUpdateParams, backoffDelayMs, constructEvent, createAppRequester, createGraph8AppClient, createGraph8ServiceClient, createTokenManager, exchangeBrowserToken, exchangeServiceToken, g8, isRetryableStatus, paginate, parseRetryAfter, request };
4970
+ export { type AddToSequenceConfig, type AgencyClient, type AgencyInfo, type App, type AppCreateParams, type AppDomain, type AppInstallation, type AppLimit, type AppLogs, type AppRequest, type AppRequestOptions, type AppSecretMetadata, type AppSourceParams, type AppStatus, type AppTokenResponse, type AppUsageSummary, type AudienceSync, type AudienceSyncCreateParams, type AudienceSyncError, type AudienceSyncMode, type AudienceSyncPlatform, type AudienceSyncRun, type AudienceSyncUpdateParams, type Booking, type BookingRequest, type CalendarConfig, type CallGradingResult, type Campaign, type CampaignCreateConfig, type CampaignLaunchExecution, type CampaignLaunchResult, type ChatConfig, type Company, type CompanyColumn, type CompanyColumnCreateParams, type CompanyContact, type CompanyEnrichment, type CompanyListParams, type CompanyUpdateParams, type ConstructEventOptions, type Contact, type ContactColumn, type ContactColumnCreateParams, type ContactCreateParams, type ContactDeal, type ContactList, type ContactListParams, type ContactUpdateParams, type ContainerLog, type CopilotConfig, type CreateDeploymentParams, type CreatedField, type CustomObject, type CustomObjectAttribute, type CustomObjectHistory, type CustomObjectHistoryEntry, type CustomObjectRecord, DEFAULT_APP_API, type Deal, type DealCreateParams, type DealListParams, type DealUpdateParams, type Deployment, type DeploymentStatus, type DialerAgentSummary, type DialerAgentsListParams, type DialerAgentsListResult, type DialerNumberInfo, type DialerNumbersListResult, type DialerReportFilters, type DialerReportMetric, type DialerSessionCreateParams, type DialerSessionCreateResult, type DialerSessionResumeResult, type DialerSessionStatus, type DialerSessionStatusUpdateResult, type DialerSessionSummary, type DialerSessionsListParams, type DialerSessionsListResult, type DialerStatsParams, type DialerStatsResult, type DomainVerificationInstructions, type DomainVerificationStatus, type EmailVerification, type EnrichLookupResult, type EvidenceKey, type Field, type FieldCreateParams, type FieldDeleteParams, type G8Config, G8Error, type G8PrivacyConfig, type GlobalContextDocument, type Graph8AppClient, type Graph8AppClientConfig, type Graph8ServiceClient, type Graph8ServiceClientConfig, type ICP, type IdentifyProperties, type InboxAssignResult, type InboxAssignee, type InboxChannel, type InboxContact, type InboxDraft, type InboxListParams, type InboxMessage, type InboxSendParams, type InboxSendResult, type InboxTag, type InboxTagResult, type InboxThread, type InstallStatus, type IntelligenceData, type IntentCompany, type IntentContact, type IntentKeyword, type IntentPage, type IntentSignals, type IntentStats, type IntentVisitor, KNOWN_WEBHOOK_EVENTS, type ListContact, type ListRecordsParams, MAX_TAIL_LINES, MIN_TAIL_LINES, type MarketplaceHiring, type MarketplaceOffer, type MarketplaceProfile, type MeetingAnalysis, type MeetingAttendee, type MeetingDetail, type MeetingListParams, type MeetingSummary, type MeetingTranscriptLine, type MissedCallback, type MissedCallbacksResult, type NodeTypeSchema, type Note, type ObjectPagination, type PaginatedResponse, type PaginationMeta$1 as PaginationMeta, type PersonEnrichment, type Persona, type Pipeline, type PipelineStage, type PipelineSuggestion, type QuotableProduct, type QuoteCreateParams, type QuoteDetail, type QuoteLineItem, type QuoteListParams, type QuoteSendParams, type QuoteSettings, type QuoteStatus, type QuoteSummary, type QuoteUpdateParams, type RequestOptions, type ResearchReport, type SchemaVersion, type SchemaVersionStatus, type SearchCompanyItem, type SearchCondition, type SearchContactItem, type SearchFilter, type SearchOperator, type SearchParams, type SearchResults, type SearchSaveParams, type SearchSaveResult, type Sequence, type SequenceActionResult, type SequenceAnalytics, type SequenceChannelConfig, type SequenceContactItem, type SequenceContactsParams, type SequenceCreateParams, type SequenceCreateResult, type SequenceDetail, type SequenceKind, type SequenceListItem, type SequenceListParams, type SequencePreview, type SequencePreviewChannel, type SequencePreviewStep, type SequenceStepConfig, type SequenceStepInputType, type SequenceStepType, type SequenceStepUpdateParams, type SequenceUpdateParams, type SetFieldValueParams, type Skill, type SkillCreateAPIParams, type SkillCreateLLMParams, type SkillInputField, type SkillListParams, type SkillTemplate, type SkillType, type SkillUpdateAPIParams, type SkillUpdateLLMParams, type Snippet, type SourceProvider, type StageCreateParams, type StagePipeline, type StagePipelineCreateParams, type StagePipelineStage, type StagePipelineUpdateParams, type StageUpdateParams, type Task, type TaskCreateParams, type TaskListParams, type TaskUpdateParams, type TimeSlot, type TokenManager, type TrackProperties, type VisitorCompany, type VisitorScore, type VoicePagination, type WebhookEvent, type WebhookEventPayload, WebhookSignatureError, type Workflow, type WorkflowConfig, type WorkflowConnection, type WorkflowCreateParams, type WorkflowExecution, type WorkflowListParams, type WorkflowNode, type WorkflowUpdateParams, backoffDelayMs, constructEvent, createAppPlatformClient, createAppRequester, createGraph8AppClient, createGraph8ServiceClient, createTokenManager, exchangeBrowserToken, exchangeServiceToken, g8, isRetryableStatus, paginate, parseRetryAfter, request };