[{"data":1,"prerenderedAt":639},["ShallowReactive",2],{"developers:\u002Fdevelopers\u002Ftypescript":3},{"doc":4,"lang":472,"nav":483,"alternatePath":583,"policy":584,"specVersion":628,"reference":7,"layout":629,"toc":630,"prev":636,"next":637,"operations":638,"overview":7,"heroExample":7},{"id":5,"title":6,"apiTag":7,"body":8,"description":469,"draft":470,"extension":471,"lang":472,"meta":473,"navTitle":7,"navigation":474,"order":475,"path":476,"rawbody":477,"section":478,"seo":479,"stem":480,"translationKey":481,"version":7,"__hash__":482},"developers_en\u002Fdevelopers\u002Ftypescript.md","TypeScript SDK",null,{"type":9,"value":10,"toc":460},"minimark",[11,35,40,49,59,76,86,90,101,109,119,125,151,155,162,168,190,235,256,260,266,273,328,345,419,440,444],[12,13,14,15,19,20,24,25,34],"p",{},"The official TypeScript SDK, ",[16,17,18],"code",{},"@totemstudioai\u002Fsdk",", covers every endpoint of the read-only ",[21,22,23],"strong",{},"Beta"," API. It runs on your server with Node.js 22.12 or later. A team administrator creates its key in ",[26,27,31],"a",{"href":28,"rel":29},"https:\u002F\u002Fapp.totemstudio.ai\u002Fsettings?tab=developers",[30],"nofollow",[21,32,33],{},"Settings → Developers","; public API access is included from Pro.",[36,37,39],"h2",{"id":38},"install-the-typescript-sdk","Install the TypeScript SDK",[12,41,42,43,48],{},"Install the release tarball from the ",[26,44,47],{"href":45,"rel":46},"https:\u002F\u002Fgithub.com\u002Fkiketordera\u002Ftotem-studio-typescript",[30],"official GitHub repository",". It contains the built package, so it needs no build step and works with install scripts disabled. Download it with its checksum, check it, then install the file you checked:",[50,51,57],"pre",{"className":52,"code":54,"language":55,"meta":56},[53],"language-bash","curl -fLO https:\u002F\u002Fgithub.com\u002Fkiketordera\u002Ftotem-studio-typescript\u002Freleases\u002Fdownload\u002Fv0.1.0-beta.2\u002Ftotemstudioai-sdk-0.1.0-beta.2.tgz\ncurl -fLO https:\u002F\u002Fgithub.com\u002Fkiketordera\u002Ftotem-studio-typescript\u002Freleases\u002Fdownload\u002Fv0.1.0-beta.2\u002Ftotemstudioai-sdk-0.1.0-beta.2.tgz.sha256\nshasum -a 256 -c totemstudioai-sdk-0.1.0-beta.2.tgz.sha256\nnpm install .\u002Ftotemstudioai-sdk-0.1.0-beta.2.tgz\n","bash","",[16,58,54],{"__ignoreMap":56},[12,60,61,62,67,68,71,72,75],{},"The checksum shows that your download is complete and unchanged; it comes from the same ",[26,63,66],{"href":64,"rel":65},"https:\u002F\u002Fgithub.com\u002Fkiketordera\u002Ftotem-studio-typescript\u002Freleases",[30],"release page"," as the tarball, so it does not prove who built the file. npm records the dependency as a ",[16,69,70],{},"file:"," path to that tarball, so keep the tarball where you installed it from. You can also install the Git tag with ",[16,73,74],{},"npm install github:kiketordera\u002Ftotem-studio-typescript#v0.1.0-beta.2",", which builds the package during installation and therefore needs install scripts enabled.",[12,77,78,79,81,82,85],{},"Either way the package is imported as ",[16,80,18],{},". It is not published on the npm registry yet, so a package with that name on npm is not Totem's: never give it your key, and install the SDK only in one of the two ways above. Keep your key in your server's secret store and provide it as ",[16,83,84],{},"TOTEM_API_KEY",". Never bundle this client or its key into a browser or mobile app.",[36,87,89],{"id":88},"make-a-typed-request","Make a typed request",[12,91,92,93,96,97,100],{},"The examples on this page are ES modules and use ",[16,94,95],{},"await"," at the top level. In a CommonJS project, put them inside an ",[16,98,99],{},"async"," function.",[50,102,107],{"className":103,"code":105,"language":106,"meta":56},[104],"language-ts","import { TotemClient } from '@totemstudioai\u002Fsdk'\n\nconst apiKey = process.env.TOTEM_API_KEY\nif (!apiKey) throw new Error('Set TOTEM_API_KEY on your server')\n\nconst client = new TotemClient({ apiKey })\nconst integration = await client.me.get()\nconst teams = await client.teams.list()\nconsole.log(integration.id, teams.data.map(team => team.id))\n","ts",[16,108,105],{"__ignoreMap":56},[12,110,111,112,115,116,118],{},"For a key that reads several teams, select one with the client's ",[16,113,114],{},"team"," option. You can also pass ",[16,117,114],{}," per request on the routes that read one team's collection:",[50,120,123],{"className":121,"code":122,"language":106,"meta":56},[104],"const team = process.env.TOTEM_TEAM_ID\nif (!team) throw new Error('Set TOTEM_TEAM_ID on your server')\n\nconst client = new TotemClient({ apiKey, team })\nconst page = await client.leads.list({ limit: 100 })\nconst matching = await client.leads.search({ email: 'alex.rivera@example.com' })\nconsole.log(page.data.length, matching.data.length)\n",[16,124,122],{"__ignoreMap":56},[12,126,127,128,131,132,134,135,137,138,141,142,145,146,150],{},"A route that reads one record by its id, such as ",[16,129,130],{},"client.leads.get(id)",", takes the team from the id and has no ",[16,133,114],{}," option: compare the record's ",[16,136,114],{}," with the one you expect. The client supplies ",[16,139,140],{},"Authorization"," and ",[16,143,144],{},"Totem-Team",", encodes filters and returns typed response objects. Field names stay the same as the API's JSON. Fields with a fixed set of values are typed so that a value added later still compiles, because ",[26,147,149],{"href":148},"\u002Fdevelopers\u002Fconventions","enums can grow",".",[36,152,154],{"id":153},"read-every-page-with-the-sdk","Read every page with the SDK",[12,156,157,158,161],{},"Use ",[16,159,160],{},"items"," to read a list without managing its page cursors:",[50,163,166],{"className":164,"code":165,"language":106,"meta":56},[104],"for await (const lead of client.items('leads.list', { query: { limit: 100 } })) {\n  console.log(lead.id, lead.version)\n}\n",[16,167,165],{"__ignoreMap":56},[12,169,157,170,173,174,177,178,181,182,185,186,189],{},[16,171,172],{},"pages"," when you need the whole page envelope. It stops once ",[16,175,176],{},"has_more"," is ",[16,179,180],{},"false","; it is not a scheduler. ",[16,183,184],{},"timeoutMs"," applies to each page; pass ",[16,187,188],{},"signal: AbortSignal.timeout(ms)"," to bound a whole traversal.",[12,191,192,193,195,196,199,200,202,203,206,207,210,211,214,215,195,218,221,222,225,226,229,230,234],{},"Read the changes feed with ",[16,194,172],{}," or ",[16,197,198],{},"client.sync.changes({ cursor, limit: 100 })",", never with ",[16,201,160],{},": apply each page before saving its ",[16,204,205],{},"next_cursor",", including on an empty page with ",[16,208,209],{},"has_more: false",". A ",[16,212,213],{},"cursor"," that is ",[16,216,217],{},"undefined",[16,219,220],{},"null"," starts from the beginning. Keep one cursor per team and resume polling every 1 to 5 minutes. Use ",[16,223,224],{},"isFeedRemoval(item)"," to tell a removal from a record's current state, and apply an item only when its ",[16,227,228],{},"version"," is greater than the one you hold. ",[26,231,233],{"href":232},"\u002Fdevelopers\u002Fsync","Keep a copy in sync"," explains removals, versions and full resync; the SDK does not store your data or cursors for you.",[236,237,240],"dev-callout",{"title":238,"type":239},"SDK or reference client?","note",[12,241,242,243,247,248,255],{},"Use the SDK for typed requests, lookups and pagination. To keep a copy of a team, start from the ",[26,244,246],{"href":245},"\u002Fdevelopers\u002Fsync#tested-reference-client","tested reference client"," of the sync guide, which implements the tombstones, the mark and sweep of a full resync and one outcome per team, or follow the SDK's ",[26,249,252],{"href":250,"rel":251},"https:\u002F\u002Fgithub.com\u002Fkiketordera\u002Ftotem-studio-typescript\u002Fblob\u002Fmain\u002Fexamples\u002Fsync.ts",[30],[16,253,254],{},"examples\u002Fsync.ts",", which syncs one team and leaves the full resync to your store.",[36,257,259],{"id":258},"sdk-errors-and-response-metadata","SDK errors and response metadata",[50,261,264],{"className":262,"code":263,"language":106,"meta":56},[104],"import { TotemApiError, TotemError } from '@totemstudioai\u002Fsdk'\n\ntry {\n  const response = await client.requestWithResponse('me.get')\n  console.log(response.requestId, response.data.id)\n} catch (error) {\n  if (error instanceof TotemApiError) {\n    console.error(error.status, error.code, error.action, error.param, error.requestId)\n  } else if (error instanceof TotemError) {\n    console.error(error.name)\n  }\n  throw error\n}\n",[16,265,263],{"__ignoreMap":56},[12,267,268,269,272],{},"Every error the SDK raises for a request it sent extends ",[16,270,271],{},"TotemError",":",[274,275,276,302,318],"ul",{},[277,278,279,282,283,285,286,289,290,293,294,297,298,301],"li",{},[16,280,281],{},"TotemApiError"," for an error the API answered. It exposes the HTTP status, the API error ",[16,284,16],{},", its recommended ",[16,287,288],{},"action",", the ",[16,291,292],{},"param"," at fault, ",[16,295,296],{},"title",", the request id and ",[16,299,300],{},"retryAfterMs"," when supplied.",[277,303,304,307,308,311,312,195,315,150],{},[16,305,306],{},"TotemProtocolError"," for a response the contract does not allow, such as a successful answer whose body is not JSON, a list page without ",[16,309,310],{},"data",", or a missing or repeated cursor during ",[16,313,314],{},"pages()",[16,316,317],{},"items()",[277,319,320,323,324,327],{},[16,321,322],{},"TotemConnectionError"," for a network failure that retries could not recover, and ",[16,325,326],{},"TotemTimeoutError"," for the request's deadline.",[12,329,330,331,195,334,336,337,340,341,344],{},"Invalid options or arguments, such as an empty ",[16,332,333],{},"apiKey",[16,335,114],{},", throw a plain ",[16,338,339],{},"TypeError"," before any request is sent, and your own ",[16,342,343],{},"signal","'s abort reason is rethrown unchanged.",[12,346,347,348,350,351,354,355,354,358,354,361,354,364,354,367,354,370,354,373,195,376,379,380,383,384,388,389,392,393,195,396,399,400,403,404,407,408,411,412,414,415,150],{},"Branch on ",[16,349,288],{},", the SDK's grouping of error codes: ",[16,352,353],{},"fix_request",", ",[16,356,357],{},"check_credentials",[16,359,360],{},"resync",[16,362,363],{},"wait_capture",[16,365,366],{},"drop_team",[16,368,369],{},"keep_and_retry",[16,371,372],{},"retry_after",[16,374,375],{},"backoff",[16,377,378],{},"contact_support",". The exported ",[16,381,382],{},"errorCatalogue"," maps every documented code to its action, and the ",[26,385,387],{"href":386},"\u002Fdevelopers\u002Ferrors","error catalogue"," explains each code; handle an unknown code by its HTTP status. On the changes feed, ",[16,390,391],{},"action === 'resync'"," (",[16,394,395],{},"resync_required",[16,397,398],{},"sync_cursor_expired",") means a full resync; ",[16,401,402],{},"capture_not_ready"," means keep your data and cursor and try again later; ",[16,405,406],{},"team_not_accessible"," means read ",[16,409,410],{},"GET \u002Fv1\u002Fteams"," again and drop the team only if it is no longer listed. Without the SDK, branch on the response's ",[16,413,16],{},". Keep the request id for ",[26,416,418],{"href":417},"\u002Fdevelopers\u002Fsupport","support",[12,420,421,422,425,426,429,430,354,432,354,435,141,437,439],{},"The client makes bounded, jittered retries for temporary failures and respects ",[16,423,424],{},"Retry-After",". A wait beyond ",[16,427,428],{},"maxRetryDelayMs",", or beyond the time left before the request's deadline, is returned to your code at once, rather than shortened. Use ",[16,431,184],{},[16,433,434],{},"maxRetries",[16,436,428],{},[16,438,343],{}," to fit your job's deadline. Authentication, authorization and invalid-request errors need a correction, not a retry loop.",[36,441,443],{"id":442},"verify-your-sdk-integration","Verify your SDK integration",[12,445,446,447,450,451,454,455,459],{},"Inject a ",[16,448,449],{},"fetch"," implementation through ",[16,452,453],{},"new TotemClient({ apiKey, fetch })"," for deterministic HTTP tests. Test your receiver's version handling, removals and cursor persistence separately, then run real requests with your own key. ",[26,456,458],{"href":457},"\u002Fdevelopers\u002Ftesting","Testing and go-live"," lists the behavior to verify; a mocked response does not prove a live key or server works.",{"title":56,"searchDepth":461,"depth":461,"links":462},3,[463,465,466,467,468],{"id":38,"depth":464,"text":39},2,{"id":88,"depth":464,"text":89},{"id":153,"depth":464,"text":154},{"id":258,"depth":464,"text":259},{"id":442,"depth":464,"text":443},"Use the official TypeScript client to read your Totem data, paginate lists and handle API errors from your server.",false,"md","en",{},true,"5","\u002Fdevelopers\u002Ftypescript","---\ntitle: TypeScript SDK\ndescription: Use the official TypeScript client to read your Totem data, paginate lists and handle API errors from your server.\nsection: guides\norder: 5\ntranslationKey: typescript\nlang: en\ndraft: false\n---\n\nThe official TypeScript SDK, `@totemstudioai\u002Fsdk`, covers every endpoint of the read-only **Beta** API. It runs on your server with Node.js 22.12 or later. A team administrator creates its key in [**Settings → Developers**](https:\u002F\u002Fapp.totemstudio.ai\u002Fsettings?tab=developers); public API access is included from Pro.\n\n## Install the TypeScript SDK\n\nInstall the release tarball from the [official GitHub repository](https:\u002F\u002Fgithub.com\u002Fkiketordera\u002Ftotem-studio-typescript). It contains the built package, so it needs no build step and works with install scripts disabled. Download it with its checksum, check it, then install the file you checked:\n\n```bash\ncurl -fLO https:\u002F\u002Fgithub.com\u002Fkiketordera\u002Ftotem-studio-typescript\u002Freleases\u002Fdownload\u002Fv0.1.0-beta.2\u002Ftotemstudioai-sdk-0.1.0-beta.2.tgz\ncurl -fLO https:\u002F\u002Fgithub.com\u002Fkiketordera\u002Ftotem-studio-typescript\u002Freleases\u002Fdownload\u002Fv0.1.0-beta.2\u002Ftotemstudioai-sdk-0.1.0-beta.2.tgz.sha256\nshasum -a 256 -c totemstudioai-sdk-0.1.0-beta.2.tgz.sha256\nnpm install .\u002Ftotemstudioai-sdk-0.1.0-beta.2.tgz\n```\n\nThe checksum shows that your download is complete and unchanged; it comes from the same [release page](https:\u002F\u002Fgithub.com\u002Fkiketordera\u002Ftotem-studio-typescript\u002Freleases) as the tarball, so it does not prove who built the file. npm records the dependency as a `file:` path to that tarball, so keep the tarball where you installed it from. You can also install the Git tag with `npm install github:kiketordera\u002Ftotem-studio-typescript#v0.1.0-beta.2`, which builds the package during installation and therefore needs install scripts enabled.\n\nEither way the package is imported as `@totemstudioai\u002Fsdk`. It is not published on the npm registry yet, so a package with that name on npm is not Totem's: never give it your key, and install the SDK only in one of the two ways above. Keep your key in your server's secret store and provide it as `TOTEM_API_KEY`. Never bundle this client or its key into a browser or mobile app.\n\n## Make a typed request\n\nThe examples on this page are ES modules and use `await` at the top level. In a CommonJS project, put them inside an `async` function.\n\n```ts\nimport { TotemClient } from '@totemstudioai\u002Fsdk'\n\nconst apiKey = process.env.TOTEM_API_KEY\nif (!apiKey) throw new Error('Set TOTEM_API_KEY on your server')\n\nconst client = new TotemClient({ apiKey })\nconst integration = await client.me.get()\nconst teams = await client.teams.list()\nconsole.log(integration.id, teams.data.map(team => team.id))\n```\n\nFor a key that reads several teams, select one with the client's `team` option. You can also pass `team` per request on the routes that read one team's collection:\n\n```ts\nconst team = process.env.TOTEM_TEAM_ID\nif (!team) throw new Error('Set TOTEM_TEAM_ID on your server')\n\nconst client = new TotemClient({ apiKey, team })\nconst page = await client.leads.list({ limit: 100 })\nconst matching = await client.leads.search({ email: 'alex.rivera@example.com' })\nconsole.log(page.data.length, matching.data.length)\n```\n\nA route that reads one record by its id, such as `client.leads.get(id)`, takes the team from the id and has no `team` option: compare the record's `team` with the one you expect. The client supplies `Authorization` and `Totem-Team`, encodes filters and returns typed response objects. Field names stay the same as the API's JSON. Fields with a fixed set of values are typed so that a value added later still compiles, because [enums can grow](\u002Fdevelopers\u002Fconventions).\n\n## Read every page with the SDK\n\nUse `items` to read a list without managing its page cursors:\n\n```ts\nfor await (const lead of client.items('leads.list', { query: { limit: 100 } })) {\n  console.log(lead.id, lead.version)\n}\n```\n\nUse `pages` when you need the whole page envelope. It stops once `has_more` is `false`; it is not a scheduler. `timeoutMs` applies to each page; pass `signal: AbortSignal.timeout(ms)` to bound a whole traversal.\n\nRead the changes feed with `pages` or `client.sync.changes({ cursor, limit: 100 })`, never with `items`: apply each page before saving its `next_cursor`, including on an empty page with `has_more: false`. A `cursor` that is `undefined` or `null` starts from the beginning. Keep one cursor per team and resume polling every 1 to 5 minutes. Use `isFeedRemoval(item)` to tell a removal from a record's current state, and apply an item only when its `version` is greater than the one you hold. [Keep a copy in sync](\u002Fdevelopers\u002Fsync) explains removals, versions and full resync; the SDK does not store your data or cursors for you.\n\n::dev-callout{type=\"note\" title=\"SDK or reference client?\"}\nUse the SDK for typed requests, lookups and pagination. To keep a copy of a team, start from the [tested reference client](\u002Fdevelopers\u002Fsync#tested-reference-client) of the sync guide, which implements the tombstones, the mark and sweep of a full resync and one outcome per team, or follow the SDK's [`examples\u002Fsync.ts`](https:\u002F\u002Fgithub.com\u002Fkiketordera\u002Ftotem-studio-typescript\u002Fblob\u002Fmain\u002Fexamples\u002Fsync.ts), which syncs one team and leaves the full resync to your store.\n::\n\n## SDK errors and response metadata\n\n```ts\nimport { TotemApiError, TotemError } from '@totemstudioai\u002Fsdk'\n\ntry {\n  const response = await client.requestWithResponse('me.get')\n  console.log(response.requestId, response.data.id)\n} catch (error) {\n  if (error instanceof TotemApiError) {\n    console.error(error.status, error.code, error.action, error.param, error.requestId)\n  } else if (error instanceof TotemError) {\n    console.error(error.name)\n  }\n  throw error\n}\n```\n\nEvery error the SDK raises for a request it sent extends `TotemError`:\n\n- `TotemApiError` for an error the API answered. It exposes the HTTP status, the API error `code`, its recommended `action`, the `param` at fault, `title`, the request id and `retryAfterMs` when supplied.\n- `TotemProtocolError` for a response the contract does not allow, such as a successful answer whose body is not JSON, a list page without `data`, or a missing or repeated cursor during `pages()` or `items()`.\n- `TotemConnectionError` for a network failure that retries could not recover, and `TotemTimeoutError` for the request's deadline.\n\nInvalid options or arguments, such as an empty `apiKey` or `team`, throw a plain `TypeError` before any request is sent, and your own `signal`'s abort reason is rethrown unchanged.\n\nBranch on `action`, the SDK's grouping of error codes: `fix_request`, `check_credentials`, `resync`, `wait_capture`, `drop_team`, `keep_and_retry`, `retry_after`, `backoff` or `contact_support`. The exported `errorCatalogue` maps every documented code to its action, and the [error catalogue](\u002Fdevelopers\u002Ferrors) explains each code; handle an unknown code by its HTTP status. On the changes feed, `action === 'resync'` (`resync_required` or `sync_cursor_expired`) means a full resync; `capture_not_ready` means keep your data and cursor and try again later; `team_not_accessible` means read `GET \u002Fv1\u002Fteams` again and drop the team only if it is no longer listed. Without the SDK, branch on the response's `code`. Keep the request id for [support](\u002Fdevelopers\u002Fsupport).\n\nThe client makes bounded, jittered retries for temporary failures and respects `Retry-After`. A wait beyond `maxRetryDelayMs`, or beyond the time left before the request's deadline, is returned to your code at once, rather than shortened. Use `timeoutMs`, `maxRetries`, `maxRetryDelayMs` and `signal` to fit your job's deadline. Authentication, authorization and invalid-request errors need a correction, not a retry loop.\n\n## Verify your SDK integration\n\nInject a `fetch` implementation through `new TotemClient({ apiKey, fetch })` for deterministic HTTP tests. Test your receiver's version handling, removals and cursor persistence separately, then run real requests with your own key. [Testing and go-live](\u002Fdevelopers\u002Ftesting) lists the behavior to verify; a mocked response does not prove a live key or server works.\n","guides",{"title":6,"description":469},"developers\u002Ftypescript","typescript","Jt4uQMj7ojh8tTTnMSzuVXF82FkSzY_0xextT5jry9w",[484,499,518,565],{"section":485,"items":486},"start",[487,491,495],{"path":488,"title":489,"description":490},"\u002Fdevelopers","Overview","Read the leads, calls, conversations and bookings of your Totem teams from your own systems, and keep a copy in sync.",{"path":492,"title":493,"description":494},"\u002Fdevelopers\u002Fquickstart","Quickstart","Make your first requests to the Totem API in a few minutes. Check your key, find your team, list leads and start a sync.",{"path":496,"title":497,"description":498},"\u002Fdevelopers\u002Fauthentication","Authentication","Secret keys and where they may live, the Totem-Team header for keys with several teams, IP allowlists, and how to roll or revoke a key.",{"section":478,"items":500},[501,502,504,508,512,514],{"path":476,"title":6,"description":469},{"path":232,"title":233,"description":503},"Copy a team with the changes feed and keep the copy current. Apply pages safely, recover from errors, and start from a reference client that Totem tests.",{"path":505,"title":506,"description":507},"\u002Fdevelopers\u002Fpagination","Lists and pagination","How list endpoints return records a page at a time, how to read every page, and what order and filters a list supports.",{"path":509,"title":510,"description":511},"\u002Fdevelopers\u002Fcoverage","Data coverage","What Totem records, since when, and how to tell an empty value from a fact that was never recorded.",{"path":457,"title":458,"description":513},"How to build and test an integration safely while the API has no test environment, and what to check before you go live.",{"path":515,"title":516,"description":517},"\u002Fdevelopers\u002Fsecurity","Security and personal data","How Totem protects API keys and the data the API serves, what it records about each key, where the API runs, and what to do with the personal data you copy.",{"section":519,"items":520},"reference",[521,524,527,531,536,541,546,551,556,561],{"path":148,"title":522,"description":523},"Conventions","The notation these docs use, and the rules every response follows: ids, timestamps, empty values, amounts, enums, versions, stability, errors and untrusted text.",{"path":386,"title":525,"description":526},"Errors","The error format, how your integration should handle each kind of error, and every error code with when it happens and what to do.",{"path":528,"title":529,"description":530},"\u002Fdevelopers\u002Frate-limits","Rate limits","How much a key can read per minute and per day, what counts toward each limit, how to retry after a 429, and how long an initial sync takes.",{"path":532,"title":533,"description":534,"apiTag":535},"\u002Fdevelopers\u002Freference-account","Account, teams and members","Check that a key works and what it can read, list its teams with their time zones, list each team's members, and check that the API is up.","account",{"path":537,"title":538,"description":539,"apiTag":540},"\u002Fdevelopers\u002Freference-leads","Leads, boards and activities","List, fetch and search a team's leads and clients, read each lead's activities, and list the boards and stages they move through.","leads",{"path":542,"title":543,"description":544,"apiTag":545},"\u002Fdevelopers\u002Freference-calls","Calls","List and fetch a team's calls, with their direction, timing and a normalized outcome. No recordings or transcripts.","calls",{"path":547,"title":548,"description":549,"apiTag":550},"\u002Fdevelopers\u002Freference-conversations","Conversations","List and fetch a team's conversations on every channel, with their status, assignee, whether a person has taken them over and when the last messages came and went. Never message content.","conversations",{"path":552,"title":553,"description":554,"apiTag":555},"\u002Fdevelopers\u002Freference-bookings","Bookings and services","List and fetch a team's bookings, and list the services its customers can book.","bookings",{"path":557,"title":558,"description":559,"apiTag":560},"\u002Fdevelopers\u002Freference-sync","Changes feed","One endpoint that copies a team and then returns every change, page by page.","sync",{"path":562,"title":563,"description":564},"\u002Fdevelopers\u002Fobjects","All objects","Every object the API returns, field by field, with an example of each.",{"section":566,"items":567},"resources",[568,572,575,579],{"path":569,"title":570,"description":571},"\u002Fdevelopers\u002Fchangelog","Changelog","Changes to the Totem API, newest first, each under the date it shipped.",{"path":417,"title":573,"description":574},"Support","How to get help with the Totem API, what to include in a request, and what to do if a key leaks.",{"path":576,"title":577,"description":578},"\u002Fdevelopers\u002Fglossary","Glossary","The terms these docs use, defined in one place, each with a link to the page that explains it.",{"path":580,"title":581,"description":582},"\u002Fdevelopers\u002Ffaq","FAQ","Short answers to the questions developers ask most about the Totem API, with links to the details.","\u002Fdevelopers\u002Fes\u002Ftypescript",{"ACTIVATION_MARGIN_MS":585,"ADMIN_ACCESS_DISCLOSURE_VERSION":586,"AUDIT_RETENTION_DAYS":587,"AUTH_FAILURE_LIMITS":588,"CAPTURE_LAG_FLOOR_MS":592,"CAPTURE_LAG_P99_MS":7,"CURSOR_MAX_AGE_DAYS":593,"DIRTY_TTL_DAYS":593,"FAMILY_TEAM_SCOPE":594,"FAMILY_TEAM_SCOPE_OPTIONS":595,"FEED_SETTLE_LAG_MS":597,"GATE_REFRESH_MS":585,"INTEGRATION_NAME_LENGTH":598,"INTEGRATION_PURPOSE_LENGTH":600,"KEY_CACHE_TTL_MS":603,"KEY_STATS_RETENTION_DAYS":604,"LEAD_RESPONSE_READ_BUDGET":605,"LIST_SCAN_MAX":608,"MAX_FAMILY_INTEGRATION_TEAMS":593,"MAX_INTEGRATIONS_PER_FAMILY":609,"MAX_IP_ALLOWLIST":590,"PAGE_LIMIT":610,"PLATFORM_CONFIG_TTL_MS":613,"REMOVAL_RETENTION_DAYS":614,"REQUEST_BODY_MAX_BYTES":615,"ROLL_GRACE_DEFAULT_HOURS":616,"ROLL_GRACE_HOURS":617,"SEARCH_MAX_RESULTS":609,"SENSITIVE_SECTOR_POLICY":620,"SENSITIVE_SECTOR_POLICY_OPTIONS":621,"SYNC_DAILY_BUDGET":623,"SYNC_VELOCITY":625,"TEAM_CACHE_TTL_MS":627},60000,"2026-10-17",365,{"perIpPerMinute":589,"perLookupIdPerMinute":590,"banMs":591},60,20,600000,300000,30,"explicit_list",[594,596],"all_family_teams",10000,{"min":464,"max":599},80,{"min":601,"max":602},1,280,5000,90,{"conversations":590,"messageReads":606,"calls":607},200,50,1000,10,{"default":611,"max":612},25,100,15000,45,16384,24,[618,601,616,619],0,168,"exclude",[620,622],"allow",{"floor":624,"recordsMultiplier":461},250000,{"perMinute":626,"burst":597},2000,30000,"1.0a","guide",[631,632,633,634,635],{"id":38,"text":39,"depth":464},{"id":88,"text":89,"depth":464},{"id":153,"text":154,"depth":464},{"id":258,"text":259,"depth":464},{"id":442,"text":443,"depth":464},{"path":496,"title":497,"section":485},{"path":232,"title":233,"section":478},[],1792502790120]