{"openapi":"3.1.0","info":{"title":"TEC World API","version":"2026-05-01","description":"The TEC World REST API: read and change your workspace's data with an API key. Every call needs a bearer key, and a key never sees more than its owner can in TEC World. Guide: /developers."},"servers":[{"url":"/","description":"Current CRM host"}],"tags":[{"name":"API Index"},{"name":"Companies"},{"name":"Contacts"},{"name":"Quotes"},{"name":"Activities"},{"name":"Manufacturers"},{"name":"Products"},{"name":"Leads"},{"name":"Sales"},{"name":"Commissions"},{"name":"Inventory"},{"name":"Samples"},{"name":"Line Sheets"},{"name":"Team Directory"},{"name":"Opportunities"},{"name":"Deletions"},{"name":"Tokens"}],"paths":{"/api/v1":{"get":{"tags":["API Index"],"summary":"Validate a private API token and list available endpoints","security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Token metadata and endpoint list.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/health":{"get":{"tags":["API Index"],"summary":"Check private API token health, rate-limit settings, and recent request status","security":[{"BearerAuth":[]}],"responses":{"200":{"description":"Token health and recent request activity.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/accounts":{"get":{"tags":["Companies"],"summary":"List accounts","description":"Returns a paginated, workspace-scoped list. Requires the accounts:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["accounts:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 350 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"account_name":{"description":"The company's name (a rename follows onto its quotes, activities, contacts, sales and commissions). Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"account_status":{"description":"Status, as text (Active, Prospect, Inactive, ...). Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"city":{"description":"City. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"state":{"description":"State or region. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"zip_code":{"description":"Postal code. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"territory":{"description":"The company's territory, as the app types it (the territory code follows it unless territory_code is sent too). Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"territory_code":{"description":"The territory's code. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"zone":{"description":"Zone. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"account_manager":{"description":"The company's account manager, as the app shows it (a name, email or user id: free text). Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"type":{"description":"Company type. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"created_at":{"description":"When the company was created. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"updated_at":{"description":"When the company last changed: send it back as PATCH's expected_updated_at. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["created_at","-created_at","updated_at","-updated_at"]}},{"name":"include","in":"query","description":"Comma-separated related records to embed on each record, under the include's name as { data, has_more }: at most 100 rows per record, the child endpoint pages the rest. contacts: The company's contact links, as GET /api/v1/accounts/{id}/contacts lists them (ids only: the link's id, account_id, contact_id, created_at; oldest first). Needs the contacts:read scope too, and each link is listed only when the token owner could read that contact. An unknown name is 400 invalid_request. A key without the scope an include needs (contacts needs contacts:read) is 403 missing_scope; an owner who may not read that module is 403 forbidden. With include, pageSize is at most 50 (400 past it), and sync.includes lists what was embedded. fields narrows the record, never the embed.","schema":{"type":"string","enum":["contacts"]},"style":"form","explode":false}],"responses":{"200":{"description":"A paginated list of accounts.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Companies"],"summary":"Create a account","description":"Requires the accounts:write token scope and the token owner's edit permission on accounts. Needs an account_name. The workspace and the creator come from the token; a member's token may leave account_manager blank or set its owner, never another active member (403). The company must sit inside the token owner's edit scope, judged without an account_manager the request sets (its territory, or the owner as its creator; 403 otherwise). A parent_account_id must be a company the token's owner can read (else 404 Linked record not found) and edit (403), and may not close a loop (422 parent_loop). A company that matches companies the token can read through GET /api/v1/accounts/{id} (the same name, any case, spaces trimmed and collapsed, wildcard characters literal; or a primary_phone sharing its last seven digits) is a 409 duplicate_prevention listing up to five of them (id, name, match): use the existing one, or change the name or phone. A company the token cannot read never refuses a create, and a token without accounts:read is not duplicate-checked. A primary_phone that is not a phone number is a 400. A retry with the same Idempotency-Key answers the company as GET reads it now. Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["accounts:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"A member's token sets account_manager to another member, the company would land outside the token owner's edit scope, or its parent is outside it.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"duplicate_prevention: the company matches companies the token can read (duplicate_candidates lists up to five: id, name and match); or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"parent_loop: the parent's own tree already loops or is too deep.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/accounts/{id}":{"get":{"tags":["Companies"],"summary":"Get one account","description":"Returns one record by id. Requires the accounts:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["accounts:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}},{"name":"include","in":"query","description":"Comma-separated related records to embed on each record, under the include's name as { data, has_more }: at most 100 rows per record, the child endpoint pages the rest. contacts: The company's contact links, as GET /api/v1/accounts/{id}/contacts lists them (ids only: the link's id, account_id, contact_id, created_at; oldest first). Needs the contacts:read scope too, and each link is listed only when the token owner could read that contact. An unknown name is 400 invalid_request. A key without the scope an include needs (contacts needs contacts:read) is 403 missing_scope; an owner who may not read that module is 403 forbidden. sync.includes lists what was embedded. fields narrows the record, never the embed.","schema":{"type":"string","enum":["contacts"]},"style":"form","explode":false}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Companies"],"summary":"Update a account","description":"Changes only the fields sent; null clears one. Requires the accounts:write token scope and the token owner's edit permission on the record. Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change. Send expected_updated_at as the updated_at GET returned: a stale one is a 409 whose latestUpdatedAt is the current value, and a write that lands between this request's read and its update is a 409 either way. A member's token changes only companies its owner holds (account_manager blank, theirs, or no other active member's): a manager's token reads its reports' companies, but a change of one is a 403; and may not set account_manager to another member (403); an account_manager re-sent unchanged is no change. The company must stay inside the token owner's edit scope, judged without an account_manager the request changes (403). A territory change moves the company's sales too: it needs sales edit, and for a token owner limited to some territories or manufacturers every moved sale inside the owner's sales scope before and after (403). With the workspace's account-manager auto-fill on, a changed account_manager is copied onto the company's sales, quotes and commissions: that needs sales edit (and quotes edit when a quote changes), and for a limited token owner each changed row inside their scope (403). A member's token never moves or reassigns a sale, quote or commission its owner's own-records view hides (403). A parent the request sets or changes must be a company the owner can read (else 404 Linked record not found) and edit (403), and may not be the company itself or one of its descendants (422 parent_loop). A rename is carried onto the company's quotes, activities, contacts, sales and commissions; if that carry-over fails, the save stands and the 200 carries a warning.","security":[{"BearerAuth":["accounts:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Another member's company (a manager's report's), a member's token setting account_manager to another member, a company or parent outside the token owner's edit scope, a territory move / account-manager copy over sales, quotes or commissions outside it (or without sales / quotes edit), or a member's token whose copy would change one its owner's own-records view hides.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"parent_loop: the parent is the company itself or one of its descendants, or its tree already loops.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Companies"],"summary":"Delete one account","description":"Requires the accounts:delete token scope. A soft delete: the account leaves every list and read; only an admin can restore it, from Settings > Recently Deleted, within 30 days (restorable_until; there is no restore over the API). Needs companies manage permission for the token owner, and the company inside the owner's companies scope (else 404); a member's token deletes only a company its owner holds (account manager blank, theirs, or no other active member's: a report's company a manager's token reads is a 403). The whole delete runs at one instant: the company's contact links, tags, document links, activities and quotes (by id, and by name only for rows linked to no company and a name no other live company bears), sales and commission lines, multipliers (which also needs the owner's Edit pricing ability), and its contacts (their quotes, sales and activities unlinked, journaled for restore). A company with child companies needs cascade \"branch\": the whole branch is deleted with it, and every company in it must be inside the owner's scope (else 403). Quotes it stamps can close their opportunity. When the workspace's approval gate for this delete is on (Settings > Permissions & Safety), send approval_reason and, when it asks for one, approval_confirmation (the account's name); a missing one is a 428 approval_required naming what it needs. Send an Idempotency-Key header to retry safely (a retry without one answers 404 once the record is deleted), a new one for every new delete. deleted_at carries microseconds. At most 20 deletes per minute per key.","security":[{"BearerAuth":["accounts:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"approval_reason":{"type":["string","null"],"maxLength":1000,"description":"The approval gate's reason, when the workspace asks for one."},"approval_confirmation":{"type":["string","null"],"description":"The approval gate's typed confirmation: the account's name."},"cascade":{"type":["string","null"],"enum":["branch",null],"description":"\"branch\": delete the company's child companies with it (required when it has any)."}}}}}},"responses":{"200":{"description":"Deleted: the id, when, until when an admin can restore it, and restore \"admin\". Never the record or a child's id.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"An unknown body field or a value of the wrong type.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Account not found in this workspace, already deleted, or outside the token owner's scope.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Nothing was deleted: cascade_required (live child companies and no cascade \"branch\"; count = the children, omitted for a member's token), paid_locked (commission lines of the branch sit on paid statements; count, omitted when the owner, or a minting admin, cannot see commissions), cascade_outside_visibility (a member's token whose delete would change records its owner does not hold; count of references, a row reached two ways counted twice; commission lines count for an owner (or, on a key an admin minted, a minter) without commission access; the contacts linked to the branch's companies and the companies linked to its contacts count too; the count is omitted when it would include commission lines the token's owner or the admin who minted it cannot see); or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"428":{"description":"approval_required: the workspace's approval gate needs approval_reason (and approval_confirmation) for this delete; nothing was deleted.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/search/accounts":{"get":{"tags":["Companies"],"summary":"Search accounts","description":"Fast lookup endpoint for command palettes, MCP tools, and integrations. Requires accounts:read.","security":[{"BearerAuth":["accounts:read"]}],"parameters":[{"name":"search","in":"query","required":true,"schema":{"type":"string","maxLength":200}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Matching records.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSearchResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/contacts":{"get":{"tags":["Contacts"],"summary":"List contacts","description":"Returns a paginated, workspace-scoped list. Requires the contacts:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["contacts:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 1,500 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"email":{"description":"Email address. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"account_id":{"description":"The contact's primary company. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"created_at":{"description":"When the contact was created. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"updated_at":{"description":"When the contact last changed. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["created_at","-created_at","updated_at","-updated_at"]}},{"name":"include","in":"query","description":"Comma-separated related records to embed on each record, under the include's name as { data, has_more }: at most 100 rows per record, the child endpoint pages the rest. accounts: The contact's company links, as GET /api/v1/contacts/{id}/accounts lists them (ids only: the link's id, account_id, contact_id, created_at; oldest first). Needs the accounts:read scope too, and each link is listed only when the token owner could read that company. An unknown name is 400 invalid_request. A key without the scope an include needs (accounts needs accounts:read) is 403 missing_scope; an owner who may not read that module is 403 forbidden. With include, pageSize is at most 50 (400 past it), and sync.includes lists what was embedded. fields narrows the record, never the embed.","schema":{"type":"string","enum":["accounts"]},"style":"form","explode":false}],"responses":{"200":{"description":"A paginated list of contacts.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Contacts"],"summary":"Create a contact","description":"Requires the contacts:write token scope and the token owner's edit permission on contacts. Needs a name or an email. The owner is the token's owner. An email that is not name@domain.tld, or a phone number that is not a US or Canadian number (10 digits, or 1 and 10 digits) or an international number starting with +, is a 400. An email or phone number already on another contact in the workspace is a 409. Linking to an account (account_id) is not supported yet. Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["contacts:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/contacts/{id}":{"get":{"tags":["Contacts"],"summary":"Get one contact","description":"Returns one record by id. Requires the contacts:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["contacts:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}},{"name":"include","in":"query","description":"Comma-separated related records to embed on each record, under the include's name as { data, has_more }: at most 100 rows per record, the child endpoint pages the rest. accounts: The contact's company links, as GET /api/v1/contacts/{id}/accounts lists them (ids only: the link's id, account_id, contact_id, created_at; oldest first). Needs the accounts:read scope too, and each link is listed only when the token owner could read that company. An unknown name is 400 invalid_request. A key without the scope an include needs (accounts needs accounts:read) is 403 missing_scope; an owner who may not read that module is 403 forbidden. sync.includes lists what was embedded. fields narrows the record, never the embed.","schema":{"type":"string","enum":["accounts"]},"style":"form","explode":false}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Contacts"],"summary":"Update a contact","description":"Changes only the fields sent; null clears one. Requires the contacts:write token scope and the token owner's edit permission on the record. Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change.","security":[{"BearerAuth":["contacts:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request, or another member's contact (a manager's report's: the token reads it, its owner does not hold it).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Contacts"],"summary":"Delete one contact","description":"Requires the contacts:delete token scope. A soft delete: the contact leaves every list and read and can be restored for 30 days (restorable_until) by the key whose owner deleted it, through POST /api/v1/contacts/{id}/restore, or by an admin from Settings > Recently Deleted. Also stamps the contact's company links and its emails and phones, and clears it from its quotes (as their contact or distributor contact), sales and activities, all restorable together. Every one of those records must be in the token owner's scope (else a 403), and a member's key may change only ones its owner holds: another member's, a manager's report's included, is a 409 cascade_outside_visibility, with count. The contact itself too: a report's contact a manager's token reads is a 403. The contact is claimed before anything else is written, only while it is live and, for a member's token, only while its owner and primary company are the ones this request's read saw: a delete another request completed first is the 404 with nothing written, and a contact handed to another member, moved onto another company, or whose company's account manager changed in between is a 409 conflict, nothing deleted (the claim is checked again under the token owner's lock right after it lands, and given back). A delete that fails part-way (a 500) puts back what it wrote; should that fail too, what it wrote stays one delete a restore brings back whole. No request body. Send an Idempotency-Key header to retry safely (a retry without one answers 404 once the record is deleted), a new one for every new delete: a key never expires and a reused one answers the first result. deleted_at carries microseconds. At most 20 deletes per minute per key.","security":[{"BearerAuth":["contacts:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Deleted: the id, when, and until when it can be restored. Never the record.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Contact not found in this workspace, already deleted, or outside the token owner's scope.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"An Idempotency-Key reused with a different body; (contacts) a member's key whose delete would change records its owner cannot see; or (activities, inventory items, leads) a member's key whose record changed between this request's read and its delete (conflict, nothing deleted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/search/contacts":{"get":{"tags":["Contacts"],"summary":"Search contacts","description":"Fast lookup endpoint for command palettes, MCP tools, and integrations. Requires contacts:read.","security":[{"BearerAuth":["contacts:read"]}],"parameters":[{"name":"search","in":"query","required":true,"schema":{"type":"string","maxLength":200}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Matching records.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactSearchResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/quotes":{"get":{"tags":["Quotes"],"summary":"List quotes","description":"Returns a paginated, workspace-scoped list. Requires the quotes:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["quotes:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 200 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"quote_number":{"description":"The quote number, exact. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"stage":{"description":"The quote's stage as stored, exact (case-sensitive). Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"manufacturer":{"description":"The manufacturer's name as stored on the quote, exact. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"manufacturer_id":{"description":"The manufacturer's id. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"account":{"description":"The company's name as stored on the quote, exact. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"account_id":{"description":"The company's id. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"total":{"description":"The quote total. Operators: gte, lte.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"quote_date":{"description":"The quote date (YYYY-MM-DD). Operators: gte, lte, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"updated_at":{"description":"When the quote last changed. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"created_at":{"description":"When the quote was created. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["updated_at","-updated_at"]}}],"responses":{"200":{"description":"A paginated list of quotes.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Quotes"],"summary":"Create a quote","description":"Requires the quotes:write token scope and the token owner's quotes edit permission. Every field is optional (a blank quote is allowed, as in the app). A quote_date or exp_date left out gets the New Quote form's default (the workspace's day; that day plus the workspace's quote validity) and a quote_number left out is generated as the app's. A linked company, contact or manufacturer must be one the token owner can read (else 404 Linked record not found). A Won stage cannot be created (422 won_on_create). Answers the quote as GET reads it. Send an Idempotency-Key header to retry safely: the same key and body replay the first response. Refusals: order_draft_stage (422: the order draft stage is only an order's), won_on_create (422), unpriced_lines (422), rule_violation (422: the database refused the change), order_not_supported (409: an order is changed in the app), total_follows_lines (409: a quote with lines takes its total from them), duplicate (409: the quote_number is taken, a deleted quote's included), invalid_link (400), invalid_if_match and if_match_mismatch (400). Moving a quote into a Won stage is a 403 forbidden: it creates a Sale, which keys cannot do yet.","security":[{"BearerAuth":["quotes:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long or out of range, or a link the app refuses (invalid_link).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"A linked record not found in this workspace, or not visible to the token owner.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"duplicate (the quote_number is taken) or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"order_draft_stage, won_on_create or unpriced_lines.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/quotes/{id}":{"get":{"tags":["Quotes"],"summary":"Get one quote","description":"Returns one record by id. Requires the quotes:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["quotes:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}},{"name":"include","in":"query","description":"Comma-separated related records to embed on each record, under the include's name as { data, has_more }: at most 100 rows per record, the child endpoint pages the rest. items: The quote's line items, as GET /api/v1/quotes/{id}/items lists them (the same columns, line pricing and field-level hiding rules), in line order. An unknown name is 400 invalid_request. sync.includes lists what was embedded. fields narrows the record, never the embed.","schema":{"type":"string","enum":["items"]},"style":"form","explode":false}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/DetailResponse"},{"type":"object","properties":{"data":{"type":"object","properties":{"items":{"$ref":"#/components/schemas/EmbeddedQuoteItems","description":"Only with include=items. The quote's line items, as GET /api/v1/quotes/{id}/items lists them (the same columns, line pricing and field-level hiding rules), in line order."}}},"sync":{"type":"object","description":"Only when include was sent: the includes embedded on the record.","properties":{"includes":{"type":"array","items":{"type":"string"}}},"required":["includes"]}}}]}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Quotes"],"summary":"Update a quote","description":"Changes the fields sent (null clears one) and the fields the app derives from a link: account_id also sets account, parent_account_id and, unless account_manager is sent, account_manager; contact_id also sets contact and, without account_id, the contact's company; manufacturer_id also sets manufacturer. Requires the quotes:write token scope and the token owner's quotes edit permission on the quote (a quote the token owner cannot read is a 404). Send expected_updated_at (or the If-Match header) as the updated_at GET returned to get a 409 instead of overwriting a newer change. An order is a 409 order_not_supported. Answers the quote as GET reads it. Refusals: order_draft_stage (422: the order draft stage is only an order's), won_on_create (422), unpriced_lines (422), rule_violation (422: the database refused the change), order_not_supported (409: an order is changed in the app), total_follows_lines (409: a quote with lines takes its total from them), duplicate (409: the quote_number is taken, a deleted quote's included), invalid_link (400), invalid_if_match and if_match_mismatch (400). Moving a quote into a Won stage is a 403 forbidden: it creates a Sale, which keys cannot do yet.","security":[{"BearerAuth":["quotes:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IfMatchUpdatedAt"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotePatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteWriteResponse"}}}},"400":{"description":"Invalid body (an unknown or server-owned field, a bad type, a value too long or out of range), invalid_link, invalid_if_match or if_match_mismatch.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Quote (or a linked record) not found in this workspace, or not visible to the token owner.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Stale expected_updated_at (latestUpdatedAt names the current value), order_not_supported or total_follows_lines.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"order_draft_stage, unpriced_lines or rule_violation.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Quotes"],"summary":"Delete one quote","description":"Requires the quotes:delete token scope. A soft delete with the app's own quote delete (admin owners only): the quote leaves every list and read and can be restored for 30 days (restorable_until) by the key whose owner deleted it, through POST /api/v1/quotes/{id}/restore, or by an admin from Settings > Recently Deleted. Its activities and sales are unlinked (restorable together) and a quote.deleted event is sent. An order is a 409 order_not_supported. No request body. Send an Idempotency-Key header to retry safely: a replay answers the first result.","security":[{"BearerAuth":["quotes:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Deleted: the id, when, and until when it can be restored. Never the record.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Quote not found in this workspace, already deleted, or outside the token owner's scope.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"order_not_supported, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/search/quotes":{"get":{"tags":["Quotes"],"summary":"Search quotes","description":"Fast lookup endpoint for command palettes, MCP tools, and integrations. Requires quotes:read.","security":[{"BearerAuth":["quotes:read"]}],"parameters":[{"name":"search","in":"query","required":true,"schema":{"type":"string","maxLength":200}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Matching records.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/activities":{"get":{"tags":["Activities"],"summary":"List activities","description":"Returns a paginated, workspace-scoped list. Requires the activities:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["activities:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 1,500 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"type":{"description":"Activity type, e.g. Call, Email, Meeting, Task, Note. Defaults to Task. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"assigned_to":{"description":"A user id in the token's workspace. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"account_id":{"description":"The linked company. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"contact_id":{"description":"The linked contact. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"manufacturer_id":{"description":"The linked manufacturer. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"quote_id":{"description":"The linked quote. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"sale_id":{"description":"The linked sale. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"due_date":{"description":"ISO 8601 date or timestamp. Operators: gte, lte, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"completed":{"description":"Whether the activity is done; empty (null) counts as not done in the app. Operators: eq, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"priority":{"description":"low, medium or high (any case); empty clears it, and an empty priority (null) counts as medium in the app. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"updated_at":{"description":"When the activity last changed. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"created_at":{"description":"When the activity was created. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["due_date","-due_date","updated_at","-updated_at","created_at","-created_at"]}}],"responses":{"200":{"description":"A paginated list of activities.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Activities"],"summary":"Create a activity","description":"Requires the activities:write token scope and the token owner's edit permission on activities. Must link to an account, contact, quote, sale or manufacturer, each visible to the token's owner. A note never carries a due date. Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["activities:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/activities/{id}":{"get":{"tags":["Activities"],"summary":"Get one activitie","description":"Returns one record by id. Requires the activities:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["activities:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Activities"],"summary":"Update a activity","description":"Changes only the fields sent; null clears one. Requires the activities:write token scope and the token owner's edit permission on the record. Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change.","security":[{"BearerAuth":["activities:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request, a link the change sets is outside the token owner's scope, or another member's activity (a manager's report's: the token reads it, its owner does not hold it).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Activities"],"summary":"Delete one activity","description":"Requires the activities:delete token scope. A soft delete: the activity leaves every list and read and can be restored for 30 days (restorable_until) by the key whose owner deleted it, through POST /api/v1/activities/{id}/restore, or by an admin from Settings > Recently Deleted. Needs activities manage permission for the token owner. A member's token deletes only activities assigned to its owner, to nobody, or to no other active member: a report's activity a manager's token reads is a 403. That rule is re-checked at the instant of the delete: an activity whose assignee at the delete is not the one this request's read saw is a 409 conflict, nothing deleted (reassigned and back to the same assignee in between, it is deleted). No request body. Send an Idempotency-Key header to retry safely (a retry without one answers 404 once the record is deleted), a new one for every new delete: a key never expires and a reused one answers the first result. deleted_at carries microseconds. At most 20 deletes per minute per key.","security":[{"BearerAuth":["activities:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Deleted: the id, when, and until when it can be restored. Never the record.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Activity not found in this workspace, already deleted, or outside the token owner's scope.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"An Idempotency-Key reused with a different body; (contacts) a member's key whose delete would change records its owner cannot see; or (activities, inventory items, leads) a member's key whose record changed between this request's read and its delete (conflict, nothing deleted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/manufacturers":{"get":{"tags":["Manufacturers"],"summary":"List manufacturers","description":"Returns a paginated, workspace-scoped list. Requires the manufacturers:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["manufacturers:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 1,500 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"parent_manufacturer_id":{"description":"The parent manufacturer (set in the app). Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"mfg_territory":{"description":"The territory the manufacturer belongs to; it must stay inside the token owner's territories. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["id","-id"]}}],"responses":{"200":{"description":"A paginated list of manufacturers.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManufacturerListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Manufacturers"],"summary":"Create a manufacturer","description":"Requires the manufacturers:write token scope and the token owner's edit permission on manufacturers. Needs a manufacturer_name no other manufacturer in the workspace holds (a soft-deleted one included: 409). The manufacturer must sit inside the token owner's territories. Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["manufacturers:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManufacturerCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManufacturerWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/manufacturers/{id}":{"get":{"tags":["Manufacturers"],"summary":"Get one manufacturer","description":"Returns one record by id. Requires the manufacturers:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["manufacturers:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManufacturerResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Manufacturers"],"summary":"Update a manufacturer","description":"Changes only the fields sent; null clears one. Requires the manufacturers:write token scope and the token owner's edit permission on the record. Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change. Send expected_updated_at as the updated_at GET returned: a stale one is a 409 whose latestUpdatedAt is the current value, and a write that lands between this request's read and its update is a 409 either way. A rename is carried onto the manufacturer's quotes, sales, activities, commissions, products, inventory and project principal lists; if that carry-over fails, the save stands and the 200 carries a warning.","security":[{"BearerAuth":["manufacturers:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManufacturerPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManufacturerWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Manufacturers"],"summary":"Delete one manufacturer","description":"Requires the manufacturers:delete token scope. A soft delete: the manufacturer leaves every list and read; only an admin can restore it, from Settings > Recently Deleted, within 30 days (restorable_until; there is no restore over the API). Needs manufacturers manage permission for the token owner, and the manufacturer inside the owner's manufacturer scope (else 404). The manufacturer is stamped and its links on quotes, sales, activities, leads and commission lines are cleared (journaled, so an admin restore puts them back). When clearing stops part-way the delete still stands: the answer is 200 with warning \"detach_incomplete\", and an admin restore undoes it. When the workspace's approval gate for this delete is on (Settings > Permissions & Safety), send approval_reason and, when it asks for one, approval_confirmation (the manufacturer's name); a missing one is a 428 approval_required naming what it needs. Send an Idempotency-Key header to retry safely (a retry without one answers 404 once the record is deleted), a new one for every new delete. deleted_at carries microseconds. At most 20 deletes per minute per key.","security":[{"BearerAuth":["manufacturers:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"approval_reason":{"type":["string","null"],"maxLength":1000,"description":"The approval gate's reason, when the workspace asks for one."},"approval_confirmation":{"type":["string","null"],"description":"The approval gate's typed confirmation: the manufacturer's name."}}}}}},"responses":{"200":{"description":"Deleted: the id, when, until when an admin can restore it, and restore \"admin\". Never the record or a child's id.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"An unknown body field (cascade included: a manufacturer has no branch) or a value of the wrong type.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Manufacturer not found in this workspace, already deleted, or outside the token owner's scope.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Nothing was deleted: cascade_outside_visibility (a member's token whose delete would change quotes, sales, activities or leads its owner does not hold, or commission lines for an owner (or, on a key an admin minted, a minter) without commission access; count, omitted when it would include commission lines the token's owner or the admin who minted it cannot see); or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"428":{"description":"approval_required: the workspace's approval gate needs approval_reason (and approval_confirmation) for this delete; nothing was deleted.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/products":{"get":{"tags":["Products"],"summary":"List products","description":"Returns a paginated, workspace-scoped list. Requires the products:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["products:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 1,500 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"stock":{"description":"Whether the product is a stocked item. Operators: eq, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"manufacturer_name":{"description":"The manufacturer's name as text: with part_number, the product's catalog key in the workspace, and what a token owner limited to some manufacturers is matched by. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"part_number":{"description":"Part number: with manufacturer_name, the product's catalog key in the workspace. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"product_family":{"description":"Product family. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"product_line":{"description":"Product line. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"root_part_no":{"description":"Root part number. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"list_price":{"description":"List price. Operators: gte, lte.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"stock_price":{"description":"Stock price. Operators: gte, lte.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"upc":{"description":"UPC code. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"hou_stock":{"description":"Stock on hand in the first location stock column. Usually 0 or empty in a workspace that does not record stock here. Operators: gte, lte.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"pharr_stock":{"description":"Stock on hand in the second location stock column. Usually 0 or empty in a workspace that does not record stock here. Operators: gte, lte.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"price_code":{"description":"Price code. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"created_at":{"description":"When the product was created. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"updated_at":{"description":"When the product last changed. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["updated_at","-updated_at"]}}],"responses":{"200":{"description":"A paginated list of products.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Products"],"summary":"Create a product","description":"Requires the products:write token scope and the token owner's edit permission on products. Needs a manufacturer_name and a part_number, which must sit inside the token owner's manufacturer scope (403 otherwise). Setting a price (list_price, stock_price, unit_cost, price_code or commission_rate; null sets none) needs the token owner's Edit pricing ability (403 otherwise), and unit_cost exists only for an owner who is an admin or a manager (for any other owner it is an unknown field: 400). A manufacturer_name and part_number a deleted product still holds is a 409 deleted_key_holder naming that product's id to a token holding products:read (its deleter's key restores it); a part_number a product of the same manufacturer that the token's owner can read already has (ignoring case and formatting; _ and % are characters, not patterns) is a 409 duplicate_prevention whose duplicate_candidates list up to five of them (id, name: the manufacturer and part number, match), as a company's do: the API never creates a possible duplicate (a product of another manufacturer, or one the owner cannot read, is not one; up to 20,000 look-alike part numbers of that manufacturer are judged, more is the generic 500). A token without products:read is not duplicate-checked. multiplier, the HTS / country-of-origin pair and the manufacturer link are not taken (GET does not return them). A retry with the same Idempotency-Key answers the product as GET reads it now. Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["products:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The product would land outside the token owner's manufacturer scope, or a price is set without the owner's Edit pricing ability.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"deleted_key_holder: a deleted product holds this manufacturer_name and part_number (its id named to a token holding products:read). duplicate_prevention: a product of this manufacturer that the token can read has this part_number, ignoring case and formatting (duplicate_candidates lists up to five: id, name and match). Or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/products/{id}":{"get":{"tags":["Products"],"summary":"Get one product","description":"Returns one record by id. Requires the products:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["products:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Products"],"summary":"Update a product","description":"Changes only the fields sent; null clears one. Requires the products:write token scope and the token owner's edit permission on the record. Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change. Send expected_updated_at as the updated_at GET returned: a stale one is a 409 whose latestUpdatedAt is the current value, and a write that lands between this request's read and its update is a 409 either way. A product outside the token owner's manufacturer scope is a 404, and a change of manufacturer_name must leave it inside (403). Changing a price (list_price, stock_price, unit_cost, price_code or commission_rate; a clear to null too; a value re-sent unchanged is no change) needs the token owner's Edit pricing ability (403 otherwise), and unit_cost exists only for an owner who is an admin or a manager (for any other owner it is an unknown field: 400). A new manufacturer_name / part_number a deleted product holds is a 409 deleted_key_holder; one another product of the same manufacturer that the owner can read already has (ignoring case and formatting) is a 409 duplicate_prevention whose duplicate_candidates list up to five of them (up to 20,000 look-alike part numbers of that manufacturer are judged; more is the generic 500). A token without products:read is not duplicate-checked. Sending the stored manufacturer_name / part_number back is no change and is not judged.","security":[{"BearerAuth":["products:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The product would leave the token owner's manufacturer scope, or a price changes without the owner's Edit pricing ability.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"A stale expected_updated_at or a change in between (conflict, with latestUpdatedAt), deleted_key_holder, or duplicate_prevention (duplicate_candidates lists up to five: id, name and match).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Products"],"summary":"Delete one product","description":"Requires the products:delete token scope. A soft delete: the product leaves every list and read and can be restored for 30 days (restorable_until) by the key whose owner deleted it, through POST /api/v1/products/{id}/restore, or by an admin from Settings > Recently Deleted. Needs products manage permission for the token owner, and the product inside the owner's manufacturer scope (else 404). Only the product is stamped: its aliases, variants, channel listings, contacts and relationships hide with it, and quote and invoice lines keep pointing at it (a restore brings it back for them). Until the workspace's database has products soft delete switched on, a delete answers 503 soft_delete_unavailable and nothing is deleted (never a permanent delete). No request body. Send an Idempotency-Key header to retry safely (a retry without one answers 404 once the record is deleted), a new one for every new delete: a key never expires and a reused one answers the first result. deleted_at carries microseconds. At most 20 deletes per minute per key.","security":[{"BearerAuth":["products:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Deleted: the id, when, and until when it can be restored. Never the record.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Product not found in this workspace, already deleted, or outside the token owner's scope.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"An Idempotency-Key reused with a different body; (contacts) a member's key whose delete would change records its owner cannot see; or (activities, inventory items, leads) a member's key whose record changed between this request's read and its delete (conflict, nothing deleted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"soft_delete_unavailable: product soft delete is not switched on in this workspace's database yet; nothing was deleted.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/leads":{"get":{"tags":["Leads"],"summary":"List leads","description":"Returns a paginated, workspace-scoped list. Requires the leads:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["leads:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 1,500 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"company":{"description":"The company the lead is for. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"email":{"description":"Their email address. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"source":{"description":"Where the lead came from (Website, Trade Show, Referral, ...). Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"status":{"description":"Where the lead stands. Defaults to New. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"priority":{"description":"Hot, Warm or Cold. Defaults to Warm. Operators: eq, in.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"}},"additionalProperties":false}]},"assigned_to":{"description":"The user who owns the lead (a user id in the token's workspace). Empty unless set. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"territory":{"description":"The lead's territory, as text (a territory code or name). Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"account_id":{"description":"The company record the lead is linked to. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"contact_id":{"description":"The lead's primary contact record. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"manufacturer_id":{"description":"The manufacturer record the lead is linked to. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"next_follow_up":{"description":"The next follow-up date (YYYY-MM-DD). Operators: gte, lte, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"last_touch_at":{"description":"When the lead was last touched (set by the server). Operators: gte, lte, is_null. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"created_at":{"description":"When the lead was created. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"updated_at":{"description":"When the lead last changed. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["updated_at","-updated_at"]}}],"responses":{"200":{"description":"A paginated list of leads.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Leads"],"summary":"Create a lead","description":"Requires the leads:write token scope and the token owner's edit permission on leads. No field is required: company defaults to an empty string, status to New, priority to Warm and estimated_value to 0; last_touch_at is now. assigned_to stays empty unless sent; when sent it must be an active user of the workspace, and a member's token may not assign a lead to another member (403). The lead must land inside the token owner's lead scope, judged without the assignee the request sets (403). A linked company, contact or manufacturer must be one the token's owner can read (else 404 Linked record not found). An email that is not name@domain.tld, or a phone number that is not a US or Canadian number (10 digits, or 1 and 10 digits) or an international number starting with +, is a 400. status Lost needs lost_reason while lost reasons are on (422 lost_reason_required); Converted is set only by the convert action. Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["leads:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The lead would land outside the token owner's lead scope, or a member's token assigns it to another member.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"person_is_contact: the lead's email or phone belongs to a contact (a person is a lead or a contact, never both; only while that rule is on in the workspace's app). lead_linked_to_contact: contact_id on a lead that is not converted. Or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"lost_reason_required: status Lost without lost_reason while lost reasons are on. assignee_inactive: assigned_to is a deactivated user.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/leads/{id}":{"get":{"tags":["Leads"],"summary":"Get one lead","description":"Returns one record by id. Requires the leads:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["leads:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Leads"],"summary":"Update a lead","description":"Changes only the fields sent; null clears one. Requires the leads:write token scope and the token owner's edit permission on the record. Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change. Send expected_updated_at as the updated_at GET returned: a stale one is a 409 whose latestUpdatedAt is the current value, and a write that lands between this request's read and its update is a 409 either way. A member's token changes only leads assigned to its owner, to nobody, or to no other active member: a manager's token reads its reports' leads, but a change of one is a 403. A new assigned_to must be an active user of the workspace and, for a member's token, not another member (403). The lead must stay inside the token owner's lead scope, judged without an assignee the request sets or changes (403); a token owner limited to some territories cannot move a lead, even its own, into a territory that is not one of theirs (403). A company, contact or manufacturer the request sets or changes must be one the token's owner can read (else 404 Linked record not found). Moving the lead into Lost needs lost_reason while lost reasons are on (422 lost_reason_required).","security":[{"BearerAuth":["leads:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Another member's lead (a manager's report's), a lead that would leave the token owner's lead scope, a territory-limited token owner moving a lead (its own included) into a territory that is not one of theirs, or a member's token assigning it to another member.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"person_is_contact: the write gives an open lead the email or phone of a contact (a person is a lead or a contact, never both; only while that rule is on in the workspace's app). lead_linked_to_contact: contact_id on a lead that is not converted. reopen_converted: a closed lead reopened while it points at a contact or holds a contact's email or phone. Or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"lost_reason_required: a move into Lost without lost_reason while lost reasons are on. assignee_inactive: assigned_to is a deactivated user.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Leads"],"summary":"Delete one lead","description":"Requires the leads:delete token scope. A soft delete: the lead leaves every list and read and can be restored for 30 days (restorable_until) by the key whose owner deleted it, through POST /api/v1/leads/{id}/restore, or by an admin from Settings > Recently Deleted. Needs leads manage permission for the token owner. The lead's activities, contacts and timeline keep their rows: they hide with the lead and come back with it; nothing else changes. A member's token deletes only leads assigned to its owner, to nobody, or to no other active member: a report's lead a manager's token reads is a 403. That rule is re-checked at the instant of the delete: a lead whose assignee or updated_at at the delete is not what this request's read saw (reassigned or saved in between) is a 409 conflict, nothing deleted. Until the workspace's database has leads soft delete switched on, a delete answers 503 soft_delete_unavailable and nothing is deleted (never a permanent delete). No request body. Send an Idempotency-Key header to retry safely (a retry without one answers 404 once the record is deleted), a new one for every new delete: a key never expires and a reused one answers the first result. deleted_at carries microseconds. At most 20 deletes per minute per key.","security":[{"BearerAuth":["leads:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Deleted: the id, when, and until when it can be restored. Never the record.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Lead not found in this workspace, already deleted, or outside the token owner's scope.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"An Idempotency-Key reused with a different body; (contacts) a member's key whose delete would change records its owner cannot see; or (activities, inventory items, leads) a member's key whose record changed between this request's read and its delete (conflict, nothing deleted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"soft_delete_unavailable: lead soft delete is not switched on in this workspace's database yet; nothing was deleted.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/sales":{"get":{"tags":["Sales"],"summary":"List sales","description":"Returns a paginated, workspace-scoped list. Requires the sales:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["sales:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 450 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"invoice_no":{"description":"The invoice number. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"customer_po":{"description":"The customer's PO number. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"status":{"description":"The sale's status (free text, as in the app). Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"invoice_date":{"description":"The invoice date, YYYY-MM-DD. Operators: gte, lte, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"payment_date":{"description":"The date the principal paid, YYYY-MM-DD. Operators: gte, lte, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"net_sales":{"description":"Net sales in the workspace currency (a credit may be negative). Changing it on an existing sale needs the token owner's Edit sale amounts ability. Operators: gte, lte.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"quote_id":{"description":"The quote the sale came from (a quote the token's owner can read; one sale per quote). Linking copies the quote's lines; null keeps the copied lines. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"account_id":{"description":"The customer company (one the token's owner can read). Its name, account manager and territory are copied onto the sale. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"contact_id":{"description":"The contact (one the token's owner can read). Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"manufacturer_id":{"description":"The principal (a manufacturer the token's owner can read). Its name is copied onto the sale. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"owner_id":{"description":"The login that owns the sale (an auth user id of an active user in the workspace). A create without one is owned by the token's owner; a member's token may not hand a sale to anyone else. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"territory":{"description":"The territory. An admin owner's token only (a body value beats the one copied from the company). Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"manufacturer":{"description":"The principal's name, copied from the principal. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"created_at":{"description":"When the sale was created. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"updated_at":{"description":"When the sale last changed. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["updated_at","-updated_at"]}}],"responses":{"200":{"description":"A paginated list of sales.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/sales/{id}":{"get":{"tags":["Sales"],"summary":"Get one sale","description":"Returns one record by id. Requires the sales:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["sales:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/commissions":{"get":{"tags":["Commissions"],"summary":"List commissions","description":"Returns a paginated, workspace-scoped list. Requires the commissions:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["commissions:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 1,500 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"status":{"description":"draft, approved or paid. A line is created draft; /release and /unrelease move it. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"invoice_no":{"description":"The invoice number. Required on create. Protected: a PATCH may re-send the stored value, but a change is refused (422 protected_field). Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"po_number":{"description":"The customer's PO number. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"invoice_date":{"description":"The invoice date, YYYY-MM-DD. Operators: gte, lte, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"payment_date":{"description":"The date the principal paid, YYYY-MM-DD (its month is the statement's). Operators: gte, lte, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"manufacturer":{"description":"The principal's name. The server links the matching manufacturer. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"related_account":{"description":"The customer company's name. The server links the matching company. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"territory":{"description":"The territory. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"source_report":{"description":"The statement or report the line came from. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"created_at":{"description":"When the line was created. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["payment_date","-payment_date"]}}],"responses":{"200":{"description":"A paginated list of commissions.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/commissions/{id}":{"get":{"tags":["Commissions"],"summary":"Get one commission","description":"Returns one record by id. Requires the commissions:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["commissions:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetailResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/inventory":{"get":{"tags":["Inventory"],"summary":"List inventory","description":"Returns a paginated, workspace-scoped list. Requires the inventory:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["inventory:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}}],"responses":{"200":{"description":"A paginated list of inventory.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryItemListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Inventory"],"summary":"Create a inventory item","description":"Requires the inventory:write token scope and the token owner's edit permission on inventory. Needs at least an item_name, manufacturer, part_number or description. houston_stock defaults to 0; last_modified_by is the token's owner. The manufacturer must be inside the token owner's manufacturer scope whoever the item is assigned to, and a member's token may not assign it to another member, a manager's reports included (403 otherwise). Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["inventory:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryItemCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryItemWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/inventory/{id}":{"get":{"tags":["Inventory"],"summary":"Get one inventor","description":"Returns one record by id. Requires the inventory:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["inventory:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryItemResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Inventory"],"summary":"Update a inventory item","description":"Changes only the fields sent; null clears one. Requires the inventory:write token scope and the token owner's edit permission on the record. Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change. Send expected_updated_at as the updated_at GET returned: a stale one is a 409 whose latestUpdatedAt is the current value, and a write that lands between this request's read and its update is a 409 either way (except an ERP stock count, whose own check is expected_houston_stock). A member's token changes only items assigned to its owner or to no other active member: a manager's token reads its reports' items, but a change of one is a 403. A change of manufacturer or assignee must leave the item inside the token owner's manufacturer scope, and a member's token may not assign it to another member (403). An item an ERP owns keeps its item_name, part_number, description and manufacturer (sent unchanged they are ignored; changed: 409 erp_managed), and a stock change is a count at the ERP's main location that needs expected_houston_stock (409 stock_change when it is missing or stale, or before the first sync); a count is sent on its own: another field changed in the same request is a 409 stock_change before anything is counted.","security":[{"BearerAuth":["inventory:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryItemPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryItemWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Inventory"],"summary":"Delete one inventory item","description":"Requires the inventory:delete token scope. A soft delete: the inventory item leaves every list and read and can be restored for 30 days (restorable_until) by the key whose owner deleted it, through POST /api/v1/inventory/{id}/restore, or by an admin from Settings > Recently Deleted. Needs inventory manage permission for the token owner. An item is a leaf: its movements, balances and order lines keep their rows, and nothing else changes. A member's token deletes only items assigned to its owner or to no other active member: a report's item a manager's token reads is a 403. That rule is re-checked at the instant of the delete: an item whose assignee at the delete is not the one this request's read saw is a 409 conflict, nothing deleted (reassigned and back to the same assignee in between, it is deleted). No request body. Send an Idempotency-Key header to retry safely (a retry without one answers 404 once the record is deleted), a new one for every new delete: a key never expires and a reused one answers the first result. deleted_at carries microseconds. At most 20 deletes per minute per key.","security":[{"BearerAuth":["inventory:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Deleted: the id, when, and until when it can be restored. Never the record.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Inventory item not found in this workspace, already deleted, or outside the token owner's scope.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"An Idempotency-Key reused with a different body; (contacts) a member's key whose delete would change records its owner cannot see; or (activities, inventory items, leads) a member's key whose record changed between this request's read and its delete (conflict, nothing deleted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/samples":{"get":{"tags":["Samples"],"summary":"List samples","description":"Returns a paginated, workspace-scoped list. Requires the samples:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["samples:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}}],"responses":{"200":{"description":"A paginated list of samples.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SampleListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Samples"],"summary":"Create a sample","description":"Requires the samples:write token scope and a token owner who is a samples editor (an admin, or on the workspace's samples editor list; checked on every request). Needs at least a manufacturer, part_number or description. houston_stock defaults to 0; last_modified_by is the token's owner. workflow_state lost, damaged, requested or approved is kept; any other state is set from assigned_to (checked_out when someone has it, else available), and an assigned_to checks the sample out now. A linked company or contact must be one the token's owner can read (else 404 Linked record not found; an owner without accounts / contacts read gets 403 whatever the id names). A retry with the same Idempotency-Key answers the sample as GET reads it now. If the sample is saved but could not be read back, data is only {id}. Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["samples:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SampleCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SampleWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/samples/{id}":{"get":{"tags":["Samples"],"summary":"Get one sample","description":"Returns one record by id. Requires the samples:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["samples:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SampleResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Samples"],"summary":"Update a sample","description":"Changes only the fields sent; null clears one. Requires the samples:write token scope and a token owner who is a samples editor (an admin, or on the workspace's samples editor list; checked on every request). Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change. Send expected_updated_at as the updated_at GET returned: a stale one is a 409 whose latestUpdatedAt is the current value, and a write that lands between this request's read and its update is a 409 either way. A new assigned_to checks the sample out now and clearing it checks it in; workflow_state follows assigned_to unless it is lost, damaged, requested or approved (approved and requested stamp their time once). A company or contact the request sets or changes must be one the token's owner can read (else 404 Linked record not found; an owner without accounts / contacts read gets 403 whatever the id names). If the change is saved but the sample could not be read back, data is only {id}. A sample whose stored company or contact was deleted since it was linked takes an edit only with that field in it (null to unlink, or one the token's owner can read; else 422 link_deleted).","security":[{"BearerAuth":["samples:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SamplePatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SampleWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"link_deleted: the sample's stored company or contact was deleted since it was linked; send that field with the edit (null, or one the token's owner can read).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Samples"],"summary":"Delete one sample","description":"Requires the samples:delete token scope. A soft delete: the sample leaves every list and read and can be restored for 30 days (restorable_until) by the key whose owner deleted it, through POST /api/v1/samples/{id}/restore, or by an admin from Settings > Recently Deleted. Needs a token owner who is a samples editor (an admin, or on the workspace's samples editor list). A sample is a leaf: nothing else changes. Until the workspace's database has samples soft delete switched on, a delete answers 503 soft_delete_unavailable and nothing is deleted (never a permanent delete). No request body. Send an Idempotency-Key header to retry safely (a retry without one answers 404 once the record is deleted), a new one for every new delete: a key never expires and a reused one answers the first result. deleted_at carries microseconds. At most 20 deletes per minute per key.","security":[{"BearerAuth":["samples:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Deleted: the id, when, and until when it can be restored. Never the record.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Sample not found in this workspace, already deleted, or outside the token owner's scope.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"An Idempotency-Key reused with a different body; (contacts) a member's key whose delete would change records its owner cannot see; or (activities, inventory items, leads) a member's key whose record changed between this request's read and its delete (conflict, nothing deleted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"soft_delete_unavailable: sample soft delete is not switched on in this workspace's database yet; nothing was deleted.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/line-sheets":{"get":{"tags":["Line Sheets"],"summary":"List line sheets","description":"Returns a paginated, workspace-scoped list. Requires the documents:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["documents:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 1,500 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"manufacturer_id":{"description":"The linked manufacturer: one in the token's workspace that is not deleted. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"source_kind":{"description":"Where the file is: external_url (a web link), shared_path (a file-share path, returned as its file name only) or uploaded_file (uploaded in the app). Always external_url for a sheet the API creates or re-points. Operators: eq, in.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"}},"additionalProperties":false}]},"active":{"description":"false archives the sheet (archived_at is stamped); true brings it back. A new sheet is active unless the create says false. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"featured":{"description":"Whether the sheet is featured. Defaults to false. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]},"created_at":{"description":"When the sheet was created. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]},"updated_at":{"description":"When the sheet last changed. Operators: gte, lte. A date alone (YYYY-MM-DD) is a whole UTC day: gte from its start, lte through its end.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["created_at","-created_at","updated_at","-updated_at"]}}],"responses":{"200":{"description":"A paginated list of line sheets.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LineSheetListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Line Sheets"],"summary":"Create a line sheet","description":"Requires the line_sheets:write token scope and an admin token owner (checked on every request). Metadata only: a web link (source_url, https only, no user name or password and no control or invisible character in it); a file-share path or an upload is not possible through the API. A source_url another sheet in the workspace has (ignoring case) is a 409 duplicate_source (checked before the write, not by a database rule: two creates of one source at the same moment can both succeed). A reference_code another sheet has gets the next free -2, -3, ... suffix. active false creates it archived. Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["line_sheets:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LineSheetCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LineSheetWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/line-sheets/{id}":{"get":{"tags":["Line Sheets"],"summary":"Get one line sheet","description":"Returns one record by id. Requires the documents:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["documents:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LineSheetResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Line Sheets"],"summary":"Update a line sheet","description":"Changes only the fields sent; null clears one. Requires the line_sheets:write token scope and an admin token owner (checked on every request). Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change. active false archives the sheet, true brings it back; there is no DELETE. A new source_url makes the sheet a web link (https only); an uploaded sheet's file cannot be replaced (422 source_locked). A sheet whose stored manufacturer was deleted since it was linked takes an edit only with manufacturer_id in it (null to unlink, or a live manufacturer; else 422 manufacturer_deleted). A source_url or reference_code another sheet has is a 409. The write is conditional on the row it read: a stale expected_updated_at, or a change in between, is a 409.","security":[{"BearerAuth":["line_sheets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LineSheetPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LineSheetWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"source_locked: the sheet is an uploaded file, whose file is replaced only by an upload in the app. manufacturer_deleted: the sheet's stored manufacturer was deleted; send manufacturer_id with the edit (null, or a live manufacturer).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/users":{"get":{"tags":["Team Directory"],"summary":"List the team directory","description":"Any valid private API token; no scope needed. Every user of the workspace, deactivated and removed users included (active is false for them, so an older record's assigned_to id still resolves to a name). Each user carries id, user_name, email, status, active, created_at and updated_at, nothing else. Read only. Oldest first; search matches user_name and email.","security":[{"BearerAuth":[]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 1,500 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"status":{"description":"The user's status as stored (Active, Inactive, ...); active says whether it lets them sign in. Operators: eq.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["created_at","-created_at","updated_at","-updated_at"]}}],"responses":{"200":{"description":"A paginated list of users.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/users/{id}":{"get":{"tags":["Team Directory"],"summary":"Get one user from the team directory","description":"Any valid private API token; no scope needed. Every user of the workspace, deactivated and removed users included (active is false for them, so an older record's assigned_to id still resolves to a name). Each user carries id, user_name, email, status, active, created_at and updated_at, nothing else. Read only. Another workspace's user is a 404, like an unknown id.","security":[{"BearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"User not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/opportunities":{"get":{"tags":["Opportunities"],"summary":"List opportunities","description":"Returns a paginated, workspace-scoped list. Requires the opportunities:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["opportunities:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}},{"name":"filter","in":"query","style":"deepObject","explode":true,"description":"filter[<field>]=value (equals) or filter[<field>][<op>]=value. At most 10 filters, 50 values per in, 200 characters per value and 1,500 bytes of filter parameters; an unknown field, operator or value is a 400 invalid_request. Text matches exactly. Changing filters invalidates a cursor.","schema":{"type":"object","properties":{"account_id":{"description":"The project's company (a company id in the token's workspace), or null. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"contact_id":{"description":"The project's contact (a contact id the key can read), or null. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"stage":{"description":"The stage, as configured in the workspace's project stages. Operators: eq, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"expected_close":{"description":"Expected close date, YYYY-MM-DD. Operators: gte, lte, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"gte":{"type":"string","description":"on or after / at least"},"lte":{"type":"string","description":"on or before / at most"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]},"owner_user_id":{"description":"The owner (an active user in the token's workspace). A create without one is owned by the key's owner. Operators: eq, in, is_null.","oneOf":[{"type":"string"},{"type":"object","properties":{"eq":{"type":"string","description":"equals (text: exact match)"},"in":{"type":"string","description":"one of up to 50 comma-separated values"},"is_null":{"type":"string","description":"true: empty; false: has a value"}},"additionalProperties":false}]}},"additionalProperties":false}},{"name":"sort","in":"query","description":"One field; a leading - sorts descending. Empty values sort last in both directions. Changing the sort invalidates a cursor.","schema":{"type":"string","enum":["expected_close","-expected_close","created_at","-created_at","updated_at","-updated_at"]}}],"responses":{"200":{"description":"A paginated list of opportunities.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Opportunities"],"summary":"Create a opportunity","description":"Requires the opportunities:write token scope and the token owner's edit permission on opportunities. Needs a name. Without owner_user_id the project is owned by the token's owner. The company and contact (each one the token's owner can read) must leave the project inside the owner's scope. Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["opportunities:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/opportunities/{id}":{"get":{"tags":["Opportunities"],"summary":"Get one opportunitie","description":"Returns one record by id. Requires the opportunities:read token scope and the token owner's matching CRM visibility.","security":[{"BearerAuth":["opportunities:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string"}}],"responses":{"200":{"description":"Record found.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Opportunities"],"summary":"Update a opportunity","description":"Changes only the fields sent; null clears one. Requires the opportunities:write token scope and the token owner's edit permission on the record. Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change.","security":[{"BearerAuth":["opportunities:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IfMatchUpdatedAt"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape). An If-Match that is not a timestamp (invalid_if_match) or names another version than expected_updated_at (if_match_mismatch).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Opportunities"],"summary":"Delete one opportunity","description":"Requires the opportunities:delete token scope. A soft delete: the opportunity leaves every list and read and can be restored for 30 days (restorable_until) by the key whose owner deleted it, through POST /api/v1/opportunities/{id}/restore, or by an admin from Settings > Recently Deleted. Needs quotes edit permission for the token owner, and the opportunity inside the owner's quotes scope (else 404); a member's token deletes and restores only opportunities its owner owns (else 404). Only the opportunity is stamped: its quotes keep their link to it and come back under it on a restore; nothing else changes. Until the workspace's database has opportunities soft delete switched on, a delete answers 503 soft_delete_unavailable and nothing is deleted. No request body. Send an Idempotency-Key header to retry safely (a retry without one answers 404 once the record is deleted), a new one for every new delete: a key never expires and a reused one answers the first result. deleted_at carries microseconds. At most 20 deletes per minute per key.","security":[{"BearerAuth":["opportunities:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Deleted: the id, when, and until when it can be restored. Never the record.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResult"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Opportunity not found in this workspace, already deleted, or outside the token owner's scope.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"An Idempotency-Key reused with a different body; (contacts) a member's key whose delete would change records its owner cannot see; or (activities, inventory items, leads) a member's key whose record changed between this request's read and its delete (conflict, nothing deleted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"soft_delete_unavailable: opportunity soft delete is not switched on in this workspace's database yet; nothing was deleted.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/quotes/{id}/items":{"get":{"tags":["Quotes"],"summary":"List one quote's line items","description":"Returns a quote's line items in line order, with the quote's total and updated_at. Requires the quotes:read token scope and the token owner's matching CRM visibility of the quote: a quote the owner could not read through GET /api/v1/quotes/{id} is the same 404, and its lines are never read. The list price, multiplier, margin and the basis the multiplier was picked by (multiplier_source, price_code, tier, region) are null unless the token owner, and for a token an admin created for its owner that admin too, may view multipliers. When the owner's role has the quote Total hidden, the total and every line price are left out. cost is never returned. At most 500 lines: a quote with more answers 422 too_many_lines.","security":[{"BearerAuth":["quotes:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for each line. id is retained.","schema":{"type":"string"}}],"responses":{"200":{"description":"The quote's line items.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteItemListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Quote not found in this workspace, or not visible to the token owner.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The quote has more than 500 line items (too_many_lines).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Quote line items are not available yet in this workspace (not_available_yet).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/accounts/{id}/contacts":{"get":{"tags":["Companies"],"summary":"List one company's contact links","description":"Returns the contacts linked to one company (the link rows), oldest link first, as ids only: each row is id (the link's own id), account_id, contact_id and created_at, never a name, email or phone. Requires the accounts:read token scope and the token owner's matching CRM visibility of the company: a company the owner could not read through GET /api/v1/accounts/{id} is the same 404, and its links are never read. A linked contact is listed only when the token also holds contacts:read and its owner could read that contact through GET /api/v1/contacts/{id} (the contacts module, the row scope and the own-records lock); any other link is left out and not counted, so a token without contacts:read gets an empty list. A contact's primary company (account_id on GET /api/v1/contacts/{id}) that has no link row of its own is not listed. A removed link simply leaves the list (one removed in the app is deleted outright, with no record of the removal), so a synced copy re-reads the list to drop it. Links have no updated_at, so updatedSince is ignored; createdSince and cursor work as on the other lists. No search, filter or sort (a filter or sort is a 400).","security":[{"BearerAuth":["accounts:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"createdSince","in":"query","description":"Return links with created_at on or after this ISO timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor; pass it back unchanged, on the same path (the same company or contact) and with the same createdSince. An altered cursor, or one minted for another query or another company or contact, is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for each link. id is retained.","schema":{"type":"string","example":"id,contact_id"}}],"responses":{"200":{"description":"A page of the company's links.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountContactLinkListResponse"}}}},"400":{"description":"A bad cursor, or a filter or sort (this list takes neither).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Company not found in this workspace, or not visible to the token owner.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Companies"],"summary":"Link a contact to a company","description":"Requires the accounts:write token scope and the token owner's companies and contacts edit permission. The company must be one the token's owner reads through GET /api/v1/accounts/{id} and, for a member's token, its owner's own (account_manager blank, theirs, or no other active member's: a manager's report's company is a 403); the contact one the owner reads through GET /api/v1/contacts/{id} (else 404 Linked record not found) and, for a member's token, its owner's own (owner blank, theirs or no other active member's, or its primary company theirs), since a link change can move its primary company: a manager's report's contact is a 403, linked already or not. A token owner limited to some territories, manufacturers or sharing rules links only a contact in their own contacts (they own it, or it is linked to a company they see; 403 otherwise). The contact's primary company is set when it had none, and never replaced: one stored with no link of its own (an import, the app's contact edit, the mobile app) stays primary and is linked too while it is a live company of the workspace (audited as adopted_primary_account_id). Already linked: 200 with changed false, nothing written unless the contact's primary company had no link of its own and gets one (audited); a link this API removed earlier is restored. Body: {\"contact_id\": \"<uuid>\"}. Answers the company, with contact_id, linked and changed (and a warning when the link saved but the contact's primary company could not be updated).","security":[{"BearerAuth":["accounts:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["contact_id"],"properties":{"contact_id":{"type":"string","format":"uuid","description":"The contact to link."}}}}}},"responses":{"200":{"description":"Linked (or already was).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountContactLinkResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/contacts/{id}/accounts":{"get":{"tags":["Contacts"],"summary":"List one contact's company links","description":"Returns the companies one contact is linked to (the link rows), oldest link first, as ids only: each row is id (the link's own id), account_id, contact_id and created_at, never a name, email or phone. Requires the contacts:read token scope and the token owner's matching CRM visibility of the contact: a contact the owner could not read through GET /api/v1/contacts/{id} is the same 404, and its links are never read. A linked company is listed only when the token also holds accounts:read and its owner could read that company through GET /api/v1/accounts/{id} (the companies module, the row scope and the own-records lock); any other link is left out and not counted, so a token without accounts:read gets an empty list. A contact's primary company (account_id on GET /api/v1/contacts/{id}) that has no link row of its own is not listed. A removed link simply leaves the list (one removed in the app is deleted outright, with no record of the removal), so a synced copy re-reads the list to drop it. Links have no updated_at, so updatedSince is ignored; createdSince and cursor work as on the other lists. No search, filter or sort (a filter or sort is a 400).","security":[{"BearerAuth":["contacts:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"createdSince","in":"query","description":"Return links with created_at on or after this ISO timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor; pass it back unchanged, on the same path (the same company or contact) and with the same createdSince. An altered cursor, or one minted for another query or another company or contact, is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for each link. id is retained.","schema":{"type":"string","example":"id,contact_id"}}],"responses":{"200":{"description":"A page of the contact's links.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountContactLinkListResponse"}}}},"400":{"description":"A bad cursor, or a filter or sort (this list takes neither).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Contact not found in this workspace, or not visible to the token owner.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/inventory/{id}/movements":{"get":{"tags":["Inventory"],"summary":"List one inventory item's stock movements","description":"Returns the item's History rows (receive, remove, Move bin, Assign owner, transfers, counts), newest first (created_at, then id), 50 a page and at most 200. Requires the inventory:read token scope and the token owner's matching CRM visibility of the item: an item the owner could not read through GET /api/v1/inventory/{id} (a junk id, a deleted item, another member's or one outside the row scope) is the same 404 and its rows are never read. cursor and createdSince work as on the other lists; no search, filter or sort.","security":[{"BearerAuth":["inventory:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"createdSince","in":"query","description":"Return rows with created_at on or after this ISO timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor; pass it back unchanged, on the same path and with the same createdSince. An altered or foreign cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for each row. id is retained.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of the item's movements.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryMovementListResponse"}}}},"400":{"description":"A bad cursor, or a filter or sort (this list takes neither).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Inventory item not found in this workspace, or not visible to the token owner.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Inventory"],"summary":"Record a stock movement on an inventory item","description":"Requires the inventory:stock token scope and the token owner's inventory edit permission on the item (a member's key may not hand an item to another member). action receive and remove change houston_stock by quantity (a linked item's through the ledger function at the ERP's main location); transfer_bin sets the item's bin (bin_to) and assign_owner its owner (assigned_to, null clears). A field another action uses is an unknown field (400). mark_obsolete is not an action: set houston_stock to 0 and clear assigned_to with PATCH /api/v1/inventory/{id}. expected_houston_stock, when sent, must equal the stored stock (409 stock_stale otherwise). Requires an Idempotency-Key header (428 without one): a retry with the same key answers the first result instead of moving stock again. Answers the item as GET reads it after the movement and the movement's History row. A refusal from the stock rules answers 409 (or 400) with a stock_* code: stock_stale (the count changed since it was read), stock_over_issue (more removed than is on hand), stock_read_only (the stock is read-only), stock_not_ready (the item's stock is not set up yet), stock_location_not_linked, stock_invalid, or stock_change for any other refusal; erp_managed (409) when the quantity belongs to a linked ERP item; stock_out_of_range and over_allocated (422); duplicate (409); not_available_yet (503).","security":[{"BearerAuth":["inventory:stock"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["action"],"properties":{"action":{"type":"string","enum":["receive","remove","transfer_bin","assign_owner"]},"quantity":{"type":"integer","minimum":1,"maximum":1000000,"description":"Whole units. Required (and allowed) for receive and remove."},"note":{"type":["string","null"],"maxLength":500},"bin_to":{"type":["string","null"],"maxLength":200,"description":"transfer_bin only."},"assigned_to":{"type":["string","null"],"maxLength":200,"description":"assign_owner only; null clears the owner."},"expected_houston_stock":{"type":["integer","null"],"minimum":-2147483648,"maximum":2147483647,"description":"Compared with the stored stock, never written."}}}}}},"responses":{"201":{"description":"The movement was recorded.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryMovementResponse"}}}},"400":{"description":"Invalid body: an unknown field, a bad type, a value out of range, or a value the field's rule refuses.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Inventory item (or an inactive or unknown location) not found in this workspace, or not visible to the token owner.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"conflict (the item changed, or another request won a race, after this request read it; nothing written), an Idempotency-Key reused with a different body, or a stock refusal. A refusal from the stock rules answers 409 (or 400) with a stock_* code: stock_stale (the count changed since it was read), stock_over_issue (more removed than is on hand), stock_read_only (the stock is read-only), stock_not_ready (the item's stock is not set up yet), stock_location_not_linked, stock_invalid, or stock_change for any other refusal; erp_managed (409) when the quantity belongs to a linked ERP item; stock_out_of_range and over_allocated (422); duplicate (409); not_available_yet (503).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"stock_out_of_range or over_allocated: the quantities are outside what the item can hold.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"428":{"description":"No Idempotency-Key header.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: inventory locations or balances are not set up in this workspace yet.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/inventory/{id}/balances":{"get":{"tags":["Inventory"],"summary":"List one inventory item's balances by location","description":"Returns the item's houston_stock and its per-location balances (on_hand, reserved, inbound, damaged, unavailable), most recently changed first. Requires the inventory:read token scope and the token owner's matching CRM visibility of the item (otherwise the same 404 as GET /api/v1/inventory/{id}). At most 200 balances: an item with more answers 422 too_many_balances.","security":[{"BearerAuth":["inventory:read"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The item's balances.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryBalanceListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Inventory item not found in this workspace, or not visible to the token owner.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"The item has more than 200 balances (too_many_balances).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"patch":{"tags":["Inventory"],"summary":"Set one location's balance of an inventory item","description":"Requires the inventory:stock token scope and the token owner's inventory edit permission on the item. Sets the quantities sent for location_id; an omitted quantity keeps its stored value, and at least one is required. Unlinked item: reserved + damaged + unavailable must stay within on_hand (422 over_allocated), and the write is a compare-and-swap on the five stored quantities (409 stock_stale if they changed). Linked item: the ERP's quantities may only be re-sent unchanged (409 erp_managed); an on_hand change is a count at that location through the ledger function and needs expected_on_hand. No Idempotency-Key: a repeat sets the same values. Answers the balance after the write (and, for a linked item, its houston_stock). A refusal from the stock rules answers 409 (or 400) with a stock_* code: stock_stale (the count changed since it was read), stock_over_issue (more removed than is on hand), stock_read_only (the stock is read-only), stock_not_ready (the item's stock is not set up yet), stock_location_not_linked, stock_invalid, or stock_change for any other refusal; erp_managed (409) when the quantity belongs to a linked ERP item; stock_out_of_range and over_allocated (422); duplicate (409); not_available_yet (503).","security":[{"BearerAuth":["inventory:stock"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["location_id"],"properties":{"location_id":{"type":"string","format":"uuid"},"on_hand":{"type":"integer","minimum":0,"maximum":1000000},"reserved":{"type":"integer","minimum":0,"maximum":1000000},"inbound":{"type":"integer","minimum":0,"maximum":1000000},"damaged":{"type":"integer","minimum":0,"maximum":1000000},"unavailable":{"type":"integer","minimum":0,"maximum":1000000},"expected_on_hand":{"type":["integer","null"],"minimum":-2147483648,"maximum":2147483647,"description":"Compared with the stored on-hand, never written."}}}}}},"responses":{"200":{"description":"The balance after the write.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryBalanceResponse"}}}},"400":{"description":"Invalid body: an unknown field, a bad type, a value out of range, or a value the field's rule refuses.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Inventory item (or an inactive or unknown location) not found in this workspace, or not visible to the token owner.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"conflict (the item changed, or another request won a race, after this request read it; nothing written), an Idempotency-Key reused with a different body, or a stock refusal. A refusal from the stock rules answers 409 (or 400) with a stock_* code: stock_stale (the count changed since it was read), stock_over_issue (more removed than is on hand), stock_read_only (the stock is read-only), stock_not_ready (the item's stock is not set up yet), stock_location_not_linked, stock_invalid, or stock_change for any other refusal; erp_managed (409) when the quantity belongs to a linked ERP item; stock_out_of_range and over_allocated (422); duplicate (409); not_available_yet (503).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"stock_out_of_range or over_allocated: the quantities are outside what the item can hold.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: inventory locations or balances are not set up in this workspace yet.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/inventory/locations":{"get":{"tags":["Inventory"],"summary":"List the workspace's inventory locations","description":"Returns the workspace's stock locations, oldest first (created_at, then id), 50 a page and at most 200. Requires the inventory:read token scope. cursor and createdSince work as on the other lists; no search, filter or sort.","security":[{"BearerAuth":["inventory:read"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"createdSince","in":"query","description":"Return rows with created_at on or after this ISO timestamp.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor; pass it back unchanged, on the same path and with the same createdSince. An altered or foreign cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for each row. id is retained.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of locations.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryLocationListResponse"}}}},"400":{"description":"A bad cursor, or a filter or sort (this list takes neither).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Inventory"],"summary":"Create an inventory location","description":"Requires the inventory:stock token scope and the token owner's inventory edit permission. Creates an active location: code is required, trimmed and upper-cased (a taken code is a 409 duplicate); location_type defaults to bin and an unknown type is a 400. Locations cannot be edited or archived through the API. Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["inventory:stock"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["code"],"properties":{"code":{"type":"string","minLength":1,"maxLength":80},"name":{"type":["string","null"],"maxLength":120},"description":{"type":["string","null"],"maxLength":500},"location_type":{"type":["string","null"],"enum":["warehouse","aisle","shelf","bin","truck","other",null],"description":"One of the location types (default bin)."}}}}}},"responses":{"201":{"description":"The location was created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryLocationResponse"}}}},"400":{"description":"Invalid body: an unknown field, a bad type, a value out of range, or a value the field's rule refuses.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Inventory item (or an inactive or unknown location) not found in this workspace, or not visible to the token owner.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"conflict (the item changed, or another request won a race, after this request read it; nothing written), an Idempotency-Key reused with a different body, or a stock refusal. A refusal from the stock rules answers 409 (or 400) with a stock_* code: stock_stale (the count changed since it was read), stock_over_issue (more removed than is on hand), stock_read_only (the stock is read-only), stock_not_ready (the item's stock is not set up yet), stock_location_not_linked, stock_invalid, or stock_change for any other refusal; erp_managed (409) when the quantity belongs to a linked ERP item; stock_out_of_range and over_allocated (422); duplicate (409); not_available_yet (503).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"stock_out_of_range or over_allocated: the quantities are outside what the item can hold.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: inventory locations or balances are not set up in this workspace yet.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/deletions":{"get":{"tags":["Deletions"],"summary":"List deleted record ids of one resource","description":"Returns the ids of records of one resource that were deleted, oldest first, for a synced copy to drop. Requires the read scope of the resource named by `resource` (accounts:read for accounts, and so on) and the token owner's matching CRM visibility: a soft delete is listed only when the owner could read the record were it still live (the same own-records lock and row rule as the resource's list, on the record as stored), and a hard delete (`kind` hard, from the deletion journal, kept 12 months) by the same lock and rule on the values the record, and the company, quote or sale it was linked to, held when it was deleted, withheld when those values cannot show the owner could read it (a hard delete recorded before the journal kept those values, a link to a record that was gone or in Recently Deleted on its own, a commission line whose splits were not recorded or that the Commissions report would re-match). `kind` soft is a record that can still be brought back for 30 days; a record that is brought back leaves the feed, and one purged after that period reappears as hard where the resource is journaled. Each row carries id, resource, deletedAt and kind, nothing else. resource=account-contacts lists removed company-contact links (id is the link's id) and needs both accounts:read and contacts:read: soft is a link the API unlinked or that went to Recently Deleted with its company (a restored link leaves the feed), hard is a link the app removed or that went with its company or contact. Its rows also carry accountId and contactId. A link is listed only while the owner could read both its company and its contact now (the same rule as GET /api/v1/accounts/{id}/contacts); a link whose company or contact is gone or out of reach is withheld (drop it with that record, from its own resource's deletions). pagination.total is always a lower bound for this resource.","security":[{"BearerAuth":[]}],"parameters":[{"name":"resource","in":"query","required":true,"description":"The resource whose deletions to list. An unknown or unavailable resource is a 400 invalid_request.","schema":{"type":"string","enum":["accounts","contacts","quotes","activities","manufacturers","products","leads","sales","commissions","inventory","samples","line-sheets","opportunities","account-contacts"]}},{"name":"since","in":"query","description":"Only deletions at or after this ISO 8601 timestamp (strict; a malformed value is a 400 invalid_request). Send the time the previous run started minus 15 minutes: deletedAt is when a deletion began, so a long deletion can become visible after a run that started later than its deletedAt. Rows the overlap repeats are safe to drop again.","schema":{"type":"string","format":"date-time"}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor; pass it back unchanged with the same resource and since. A page shorter than pageSize is the last one (sync.nextCursor null). An altered cursor, or one minted for another resource or since, is rejected with 400 invalid_request.","schema":{"type":"string"}}],"responses":{"200":{"description":"A page of deleted record ids, oldest first. Follow sync.nextCursor until it is null. pagination.total is the full count from since only on the first page (no cursor) of a key whose owner reads every record of the resource; on any other page it is a lower bound, the page's rows plus one when another page follows, so pagination.hasNextPage is true exactly when sync.nextCursor is set.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletionListResponse"}}}},"400":{"description":"Unknown resource, malformed since, or a bad cursor.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/contacts/{id}/restore":{"post":{"tags":["Contacts"],"summary":"Restore one contact this key's owner deleted","description":"Requires the contacts:delete token scope. Brings back a contact the token's owner deleted within the last 30 days, with everything that delete took with it, and answers with the contact as GET returns it plus restore counts (restored per table, relinked, skipped: numbers only); a key without contacts:read (whose GET is a 403) gets only its id and the counts, on the first call and on a retry. A record someone else deleted, an unknown id and an already restored one are the same 404. No request body. Send an Idempotency-Key header to retry safely, a new one for every new restore: a retry answers the record as it reads now with the first call's counts. At most 20 restores per minute per key.","security":[{"BearerAuth":["contacts:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Restored: the record as GET returns it (only its id for a key without the read scope), plus restore counts.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactRestoreResponse"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No delete by this key's owner of that id to restore, or the record is outside the owner's view or, for a member's key, another member's (a manager's report's included).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Deleted along with a company or manufacturer (restore_cascade: an admin restores it), a member's key whose restore would bring back or re-link records its owner cannot see or does not hold, a manager's report's included (restore_outside_visibility, with count), or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"The delete is older than 30 days (restore_expired).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: the restore waits on a database update; nothing was restored or changed. Retry later.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/activities/{id}/restore":{"post":{"tags":["Activities"],"summary":"Restore one activity this key's owner deleted","description":"Requires the activities:delete token scope. Brings back a activity the token's owner deleted within the last 30 days, with everything that delete took with it, and answers with the activity as GET returns it plus restore counts (restored per table, relinked, skipped: numbers only); a key without activities:read (whose GET is a 403) gets only its id and the counts, on the first call and on a retry. A record someone else deleted, an unknown id and an already restored one are the same 404. No request body. Send an Idempotency-Key header to retry safely, a new one for every new restore: a retry answers the record as it reads now with the first call's counts. At most 20 restores per minute per key.","security":[{"BearerAuth":["activities:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Restored: the record as GET returns it (only its id for a key without the read scope), plus restore counts.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivityRestoreResponse"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No delete by this key's owner of that id to restore, or the record is outside the owner's view or, for a member's key, another member's (a manager's report's included).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Deleted along with a company or manufacturer (restore_cascade: an admin restores it), a member's key whose restore would bring back or re-link records its owner cannot see or does not hold, a manager's report's included (restore_outside_visibility, with count), or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"The delete is older than 30 days (restore_expired).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: the restore waits on a database update; nothing was restored or changed. Retry later.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/products/{id}/restore":{"post":{"tags":["Products"],"summary":"Restore one product this key's owner deleted","description":"Requires the products:delete token scope. Brings back a product the token's owner deleted within the last 30 days, with everything that delete took with it, and answers with the product as GET returns it plus restore counts (restored per table, relinked, skipped: numbers only); a key without products:read (whose GET is a 403) gets only its id and the counts, on the first call and on a retry. A record someone else deleted, an unknown id and an already restored one are the same 404. No request body. Send an Idempotency-Key header to retry safely, a new one for every new restore: a retry answers the record as it reads now with the first call's counts. At most 20 restores per minute per key.","security":[{"BearerAuth":["products:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Restored: the record as GET returns it (only its id for a key without the read scope), plus restore counts.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductRestoreResponse"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No delete by this key's owner of that id to restore, or the record is outside the owner's view or, for a member's key, another member's (a manager's report's included).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Deleted along with a company or manufacturer (restore_cascade: an admin restores it), a member's key whose restore would bring back or re-link records its owner cannot see or does not hold, a manager's report's included (restore_outside_visibility, with count), or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"The delete is older than 30 days (restore_expired).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: the restore waits on a database update; nothing was restored or changed. Retry later.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/leads/{id}/restore":{"post":{"tags":["Leads"],"summary":"Restore one lead this key's owner deleted","description":"Requires the leads:delete token scope. Brings back a lead the token's owner deleted within the last 30 days, with everything that delete took with it, and answers with the lead as GET returns it plus restore counts (restored per table, relinked, skipped: numbers only); a key without leads:read (whose GET is a 403) gets only its id and the counts, on the first call and on a retry. A record someone else deleted, an unknown id and an already restored one are the same 404. No request body. Send an Idempotency-Key header to retry safely, a new one for every new restore: a retry answers the record as it reads now with the first call's counts. At most 20 restores per minute per key.","security":[{"BearerAuth":["leads:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Restored: the record as GET returns it (only its id for a key without the read scope), plus restore counts.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadRestoreResponse"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No delete by this key's owner of that id to restore, or the record is outside the owner's view or, for a member's key, another member's (a manager's report's included).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Deleted along with a company or manufacturer (restore_cascade: an admin restores it), a member's key whose restore would bring back or re-link records its owner cannot see or does not hold, a manager's report's included (restore_outside_visibility, with count), or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"The delete is older than 30 days (restore_expired).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: the restore waits on a database update; nothing was restored or changed. Retry later.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/inventory/{id}/restore":{"post":{"tags":["Inventory"],"summary":"Restore one inventory item this key's owner deleted","description":"Requires the inventory:delete token scope. Brings back a inventory item the token's owner deleted within the last 30 days, with everything that delete took with it, and answers with the inventory item as GET returns it plus restore counts (restored per table, relinked, skipped: numbers only); a key without inventory:read (whose GET is a 403) gets only its id and the counts, on the first call and on a retry. A record someone else deleted, an unknown id and an already restored one are the same 404. No request body. Send an Idempotency-Key header to retry safely, a new one for every new restore: a retry answers the record as it reads now with the first call's counts. At most 20 restores per minute per key.","security":[{"BearerAuth":["inventory:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Restored: the record as GET returns it (only its id for a key without the read scope), plus restore counts.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryItemRestoreResponse"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No delete by this key's owner of that id to restore, or the record is outside the owner's view or, for a member's key, another member's (a manager's report's included).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Deleted along with a company or manufacturer (restore_cascade: an admin restores it), a member's key whose restore would bring back or re-link records its owner cannot see or does not hold, a manager's report's included (restore_outside_visibility, with count), or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"The delete is older than 30 days (restore_expired).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: the restore waits on a database update; nothing was restored or changed. Retry later.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/samples/{id}/restore":{"post":{"tags":["Samples"],"summary":"Restore one sample this key's owner deleted","description":"Requires the samples:delete token scope. Brings back a sample the token's owner deleted within the last 30 days, with everything that delete took with it, and answers with the sample as GET returns it plus restore counts (restored per table, relinked, skipped: numbers only); a key without samples:read (whose GET is a 403) gets only its id and the counts, on the first call and on a retry. A record someone else deleted, an unknown id and an already restored one are the same 404. No request body. Send an Idempotency-Key header to retry safely, a new one for every new restore: a retry answers the record as it reads now with the first call's counts. At most 20 restores per minute per key.","security":[{"BearerAuth":["samples:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Restored: the record as GET returns it (only its id for a key without the read scope), plus restore counts.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SampleRestoreResponse"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No delete by this key's owner of that id to restore, or the record is outside the owner's view or, for a member's key, another member's (a manager's report's included).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Deleted along with a company or manufacturer (restore_cascade: an admin restores it), a member's key whose restore would bring back or re-link records its owner cannot see or does not hold, a manager's report's included (restore_outside_visibility, with count), or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"The delete is older than 30 days (restore_expired).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: the restore waits on a database update; nothing was restored or changed. Retry later.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/leads/{id}/convert":{"post":{"tags":["Leads"],"summary":"Convert a lead into a company and a contact","description":"Requires the leads:write token scope and the token owner's leads, companies and contacts edit permission. Links the lead's company record (or the existing company whose name matches the lead's company, or a new one) and its contact record (or the contact whose email or phone matches, or a new one), joins every contact on the lead to that company and marks the lead Converted, exactly as the app's Convert. The lead must be in the token owner's lead edit scope and its linked company and contact readable by the owner (else 404). A token owner limited to some territories cannot create a company outside them (403). A lead already Converted is a 409 already_converted; a lead that changed, or that another convert (another Idempotency-Key) claimed, after this request read it is a 409 conflict. Of two converts of one lead one converts and the other is either 409, with nothing written; the converting one marks the lead Converted as it starts, so already_converted can come back while it is still running. A convert that fails part-way answers 500 and tries to give the lead back its status (best effort: a crash, a timeout or a save made meanwhile can leave it Converted with no company or contact, and every retry is then already_converted; re-read the lead and, once no convert of it can still be running, set its status back with PATCH and convert again; never set it back while one may be running, or the lead converts twice); a company or contact it created before the failure stays. No request body. Requires an Idempotency-Key header (428 without one): a retry with the same key answers the first result instead of converting again. Answers the lead as GET returns it: status Converted, account_id and contact_id the company and contact it became.","security":[{"BearerAuth":["leads:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"responses":{"200":{"description":"Converted: the lead as GET returns it.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadWriteResponse"}}}},"400":{"description":"A request body (none is accepted), or a lead phone number the contact rule refuses.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Lead (or its linked company or contact) not found in this workspace, or outside the token owner's scope.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"already_converted; conflict: the lead changed, or another convert claimed it, after this request read it (nothing written); or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"company_required: the lead has no company name and no linked company.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"428":{"description":"No Idempotency-Key header.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/accounts/{id}/contacts/{contactId}":{"delete":{"tags":["Companies"],"summary":"Unlink a contact from a company","description":"Requires the accounts:write token scope and the token owner's companies and contacts edit permission. The company must be one the token's owner reads through GET /api/v1/accounts/{id} and, for a member's token, its owner's own (account_manager blank, theirs, or no other active member's: a manager's report's company is a 403); the contact one the owner reads through GET /api/v1/contacts/{id} (else 404 Linked record not found) and, for a member's token, its owner's own (owner blank, theirs or no other active member's, or its primary company theirs), since a link change can move its primary company: a manager's report's contact is a 403, linked already or not. Changes the link only (the link row is soft-deleted; a later link restores it); neither record is deleted. The contact's primary company moves to its oldest remaining company (or is cleared) when it was this one; unlinking another company keeps it, and one stored with no link of its own is linked too while it is a live company of the workspace (audited as adopted_primary_account_id). Not linked: 409 not_linked. No body. Answers the company, with contact_id, linked and changed (and a warning when the unlink saved but the contact's primary company could not be updated).","security":[{"BearerAuth":["accounts:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"contactId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Unlinked.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountContactLinkResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"not_linked: the contact is not linked to this company.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/inventory/{id}/move":{"post":{"tags":["Inventory"],"summary":"Move stock between two locations","description":"Requires the inventory:stock token scope and the token owner's inventory edit permission on the item. Moves quantity of the item between two different active locations of the workspace through the ledger function, linked item or not. expected_from_on_hand, when sent, must equal the source's on-hand (409 stock_stale otherwise). A location that is unknown or inactive is a 404 Linked record not found. Requires an Idempotency-Key header (428 without one). Answers the movement's id, both locations, the quantity, the source's on-hand after it and the item's houston_stock after it (it moves only when the main location of a linked item is a side; null when unreported). A refusal from the stock rules answers 409 (or 400) with a stock_* code: stock_stale (the count changed since it was read), stock_over_issue (more removed than is on hand), stock_read_only (the stock is read-only), stock_not_ready (the item's stock is not set up yet), stock_location_not_linked, stock_invalid, or stock_change for any other refusal; erp_managed (409) when the quantity belongs to a linked ERP item; stock_out_of_range and over_allocated (422); duplicate (409); not_available_yet (503).","security":[{"BearerAuth":["inventory:stock"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKeyRequired"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["from_location_id","to_location_id","quantity"],"properties":{"from_location_id":{"type":"string","format":"uuid"},"to_location_id":{"type":"string","format":"uuid","description":"Must differ from from_location_id."},"quantity":{"type":"integer","minimum":1,"maximum":1000000},"expected_from_on_hand":{"type":["integer","null"],"minimum":-2147483648,"maximum":2147483647,"description":"Compared with the source's on-hand, never written."}}}}}},"responses":{"201":{"description":"The stock was moved.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryMoveResponse"}}}},"400":{"description":"Invalid body: an unknown field, a bad type, a value out of range, or a value the field's rule refuses.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Inventory item (or an inactive or unknown location) not found in this workspace, or not visible to the token owner.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"conflict (the item changed, or another request won a race, after this request read it; nothing written), an Idempotency-Key reused with a different body, or a stock refusal. A refusal from the stock rules answers 409 (or 400) with a stock_* code: stock_stale (the count changed since it was read), stock_over_issue (more removed than is on hand), stock_read_only (the stock is read-only), stock_not_ready (the item's stock is not set up yet), stock_location_not_linked, stock_invalid, or stock_change for any other refusal; erp_managed (409) when the quantity belongs to a linked ERP item; stock_out_of_range and over_allocated (422); duplicate (409); not_available_yet (503).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"stock_out_of_range or over_allocated: the quantities are outside what the item can hold.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"428":{"description":"No Idempotency-Key header.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: inventory locations or balances are not set up in this workspace yet.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/tokens":{"get":{"tags":["Tokens"],"summary":"List the workspace's private API keys","description":"Requires the tokens:manage token scope; the token owner must be an admin when the call is made. Every live key of the workspace and the newest 200 revoked ones, newest first, with each key's owner and creator. Never a secret or its hash. kind is oauth_connection for an app connected through OAuth (an AI app or a partner app), key otherwise.","security":[{"BearerAuth":["tokens:manage"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,name,revoked_at"}}],"responses":{"200":{"description":"A page of the workspace's keys.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrivateApiTokenListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/tokens/{id}":{"delete":{"tags":["Tokens"],"summary":"Revoke a private API key","description":"Requires the tokens:manage token scope; the token owner must be an admin when the call is made. Revokes any key of the workspace, the calling key included (its next call is a 401). Send the key's config_version in If-Match to get a 409 instead of revoking a key that changed since you read it. Send an Idempotency-Key header to retry safely. No request body. At most 20 revokes per minute per key.","security":[{"BearerAuth":["tokens:manage"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IfMatchConfigVersion"},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Revoked: the key as the list returns it.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrivateApiTokenResponse"}}}},"400":{"description":"A request body, or an If-Match that is not a positive integer.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Key not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Already revoked, If-Match is not the key's current config_version, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/opportunities/{id}/restore":{"post":{"tags":["Opportunities"],"summary":"Restore one opportunity this key's owner deleted","description":"Requires the opportunities:delete token scope. Brings back a opportunity the token's owner deleted within the last 30 days, with everything that delete took with it, and answers with the opportunity as GET returns it plus restore counts (restored per table, relinked, skipped: numbers only); a key without opportunities:read (whose GET is a 403) gets only its id and the counts, on the first call and on a retry. A record someone else deleted, an unknown id and an already restored one are the same 404. No request body. Send an Idempotency-Key header to retry safely, a new one for every new restore: a retry answers the record as it reads now with the first call's counts. At most 20 restores per minute per key.","security":[{"BearerAuth":["opportunities:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Restored: the record as GET returns it (only its id for a key without the read scope), plus restore counts.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityRestoreResponse"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No delete by this key's owner of that id to restore, or the record is outside the owner's view or, for a member's key, another member's (a manager's report's included).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Deleted along with a company or manufacturer (restore_cascade: an admin restores it), a member's key whose restore would bring back or re-link records its owner cannot see or does not hold, a manager's report's included (restore_outside_visibility, with count), or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"The delete is older than 30 days (restore_expired).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: the restore waits on a database update; nothing was restored or changed. Retry later.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/opportunities/{id}/quotes/{quoteId}":{"put":{"tags":["Opportunities"],"summary":"Link a quote to an opportunity","description":"Requires the opportunities:write token scope and the token owner's quotes edit permission on both records. Moves the quote from any other opportunity, so a member's token moves only a quote its owner holds (owner blank, theirs or no other active member's): a manager's report's quote is a 403, linked already or not. Already linked: 200 with changed false. A quote whose opportunity another change alters while this request links it (moved to a different one, or taken out of the one it was under): 409 conflict, nothing written (re-read it and retry); one another change links here first: 200 with changed false. No body. Answers the opportunity, with quote_id, linked and changed.","security":[{"BearerAuth":["opportunities:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Linked (or already was).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityQuoteLinkResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"conflict: another change altered the quote's opportunity (moved it to a different one, or took it out of the one it was under) between this request's read and its write. Nothing was written; re-read the quote and retry.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["Opportunities"],"summary":"Unlink a quote from an opportunity","description":"Requires the opportunities:write token scope and the token owner's quotes edit permission on both records. Changes the quote's link only; nothing is deleted. A member's token unlinks only a quote its owner holds: a manager's report's quote is a 403. Not linked to this opportunity, including a quote another change unlinks or moves while this request runs: 409 not_linked. No body. Answers the opportunity, with quote_id, linked and changed.","security":[{"BearerAuth":["opportunities:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"quoteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Unlinked (or already was not).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityQuoteLinkResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"not_linked: the quote is not under this opportunity (also when another change took it out or moved it while this request ran).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/quotes/{id}/restore":{"post":{"tags":["Quotes"],"summary":"Restore one quote this key's owner deleted","description":"Requires the quotes:delete token scope. Brings back a quote the token's owner deleted within the last 30 days, relinking the activities and sales the delete detached, and answers with the quote as GET returns it (only its id for a key without the quotes:read scope) plus restore counts (restored per table, relinked, skipped: numbers only). A quote.restored event is sent. No request body. Send an Idempotency-Key header to retry safely: a replay answers the first result.","security":[{"BearerAuth":["quotes:delete"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Restored: the quote as GET returns it, plus restore counts.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuoteWriteResponse"}}}},"400":{"description":"A request body (none is accepted).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"No delete by this key's owner of that id to restore, or the quote is outside the owner's view.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"restore_outside_visibility, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"410":{"description":"The delete is older than 30 days (restore_expired).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"not_available_yet: the restore waits on a database update; nothing was restored or changed. Retry later.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/price-sheets":{"get":{"tags":["Price Book"],"summary":"List price sheet rows","description":"Returns a paginated, workspace-scoped list ordered by updated_at. Requires the price_sheets:write token scope (no read scope exists for the price book) and the token owner's products read; every row of the workspace.","security":[{"BearerAuth":["price_sheets:write"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}}],"responses":{"200":{"description":"A paginated list of price sheet rows.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceSheetListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Price Book"],"summary":"Create a Price sheet","description":"Requires the price_sheets:write token scope and a token owner with products edit and the Edit pricing ability (checked on every request). Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["price_sheets:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceSheetCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceSheetWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/price-sheets/{id}":{"patch":{"tags":["Price Book"],"summary":"Update a Price sheet","description":"Changes only the fields sent; null clears one. Requires the price_sheets:write token scope and a token owner with products edit and the Edit pricing ability (checked on every request). Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change.","security":[{"BearerAuth":["price_sheets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceSheetPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceSheetWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/price-sheet-items":{"get":{"tags":["Price Book"],"summary":"List price sheet row rows","description":"Returns a paginated, workspace-scoped list ordered by updated_at. Requires the price_sheets:write token scope (no read scope exists for the price book) and the token owner's products read; every row of the workspace.","security":[{"BearerAuth":["price_sheets:write"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}}],"responses":{"200":{"description":"A paginated list of price sheet row rows.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceSheetRowListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Price Book"],"summary":"Create a Price sheet row","description":"Requires the price_sheets:write token scope and a token owner with products edit and the Edit pricing ability (checked on every request). Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["price_sheets:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceSheetRowCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceSheetRowWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/price-sheet-items/{id}":{"patch":{"tags":["Price Book"],"summary":"Update a Price sheet row","description":"Changes only the fields sent; null clears one. Requires the price_sheets:write token scope and a token owner with products edit and the Edit pricing ability (checked on every request). Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change.","security":[{"BearerAuth":["price_sheets:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceSheetRowPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PriceSheetRowWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/spas":{"get":{"tags":["Price Book"],"summary":"List spa rows","description":"Returns a paginated, workspace-scoped list ordered by updated_at. Requires the multiplier:write token scope (no read scope exists for the price book) and the token owner's Multiplier switch; every row of the workspace.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}}],"responses":{"200":{"description":"A paginated list of spa rows.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SPAListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Price Book"],"summary":"Create a SPA","description":"Requires the multiplier:write token scope and a token owner with multiplier edit, the Multiplier switch and the Edit pricing ability (checked on every request). Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SPACreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SPAWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/spas/{id}":{"patch":{"tags":["Price Book"],"summary":"Update a SPA","description":"Changes only the fields sent; null clears one. Requires the multiplier:write token scope and a token owner with multiplier edit, the Multiplier switch and the Edit pricing ability (checked on every request). Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SPAPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SPAWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/manufacturer-rates":{"get":{"tags":["Price Book"],"summary":"List manufacturer rate rows","description":"Returns a paginated, workspace-scoped list ordered by updated_at. Requires the multiplier:write token scope (no read scope exists for the price book) and the token owner's Multiplier switch and commissions view; only manufacturers inside the owner's manufacturers row scope, live ones only, each as id, manufacturer_name, commission_rate, commission_rate_notes and updated_at.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}}],"responses":{"200":{"description":"A paginated list of manufacturer rate rows.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManufacturerRateListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/manufacturer-rates/{id}":{"patch":{"tags":["Price Book"],"summary":"Update a Manufacturer rate","description":"Changes only the fields sent; null clears one. Requires the multiplier:write token scope and a token owner with multiplier edit and the Multiplier switch who manages commissions (commission manager plus commissions edit; checked on every request). Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManufacturerRatePatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ManufacturerRateWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/tariff-surcharges":{"get":{"tags":["Price Book"],"summary":"List tariff surcharge rows","description":"Returns a paginated, workspace-scoped list ordered by updated_at. Requires the multiplier:write token scope (no read scope exists for the price book) and the token owner's Multiplier switch; every row of the workspace.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}}],"responses":{"200":{"description":"A paginated list of tariff surcharge rows.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffSurchargeListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Price Book"],"summary":"Create a Tariff surcharge","description":"Requires the multiplier:write token scope and a token owner with multiplier edit and the Multiplier switch (checked on every request). Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffSurchargeCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffSurchargeWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/tariff-surcharges/{id}":{"patch":{"tags":["Price Book"],"summary":"Update a Tariff surcharge","description":"Changes only the fields sent; null clears one. Requires the multiplier:write token scope and a token owner with multiplier edit and the Multiplier switch (checked on every request). Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffSurchargePatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TariffSurchargeWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/tariff-origins":{"get":{"tags":["Price Book"],"summary":"List origin default rows","description":"Returns a paginated, workspace-scoped list ordered by updated_at. Requires the multiplier:write token scope (no read scope exists for the price book) and the token owner's Multiplier switch; every row of the workspace.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}}],"responses":{"200":{"description":"A paginated list of origin default rows.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginDefaultListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Price Book"],"summary":"Create a Origin default","description":"Requires the multiplier:write token scope and a token owner with multiplier edit and the Multiplier switch (checked on every request). Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginDefaultCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginDefaultWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/tariff-origins/{id}":{"patch":{"tags":["Price Book"],"summary":"Update a Origin default","description":"Changes only the fields sent; null clears one. Requires the multiplier:write token scope and a token owner with multiplier edit and the Multiplier switch (checked on every request). Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginDefaultPatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OriginDefaultWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/tariff-duty-rules":{"get":{"tags":["Price Book"],"summary":"List duty rule rows","description":"Returns a paginated, workspace-scoped list ordered by updated_at. Requires the multiplier:write token scope (no read scope exists for the price book) and the token owner's Multiplier switch; every row of the workspace.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"search","in":"query","schema":{"type":"string","maxLength":200}},{"name":"updatedSince","in":"query","description":"Return records with updated_at on or after this ISO timestamp when the endpoint supports updated_at.","schema":{"type":"string","format":"date-time"}},{"name":"createdSince","in":"query","description":"Return records with created_at on or after this ISO timestamp when the endpoint supports created_at.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque cursor returned in sync.nextCursor for stable incremental pulls. Pass it back unchanged: an altered or malformed cursor is rejected with 400 invalid_request.","schema":{"type":"string"}},{"name":"fields","in":"query","description":"Comma-separated field allowlist for slimmer responses. id is retained when available.","schema":{"type":"string","example":"id,updated_at,account_name"}}],"responses":{"200":{"description":"A paginated list of duty rule rows.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DutyRuleListResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Price Book"],"summary":"Create a Duty rule","description":"Requires the multiplier:write token scope and a token owner with multiplier edit and the Multiplier switch (checked on every request). Send an Idempotency-Key header to retry safely: the same key and body replay the first response.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DutyRuleCreate"}}}},"responses":{"201":{"description":"Created.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DutyRuleWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/price-book/tariff-duty-rules/{id}":{"patch":{"tags":["Price Book"],"summary":"Update a Duty rule","description":"Changes only the fields sent; null clears one. Requires the multiplier:write token scope and a token owner with multiplier edit and the Multiplier switch (checked on every request). Send expected_updated_at (the record's updated_at) to get a 409 instead of overwriting a newer change.","security":[{"BearerAuth":["multiplier:write"]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DutyRulePatch"}}}},"responses":{"200":{"description":"Updated.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DutyRuleWriteResponse"}}}},"400":{"description":"Invalid body: an unknown or server-owned field, a bad type, a value too long, or a value the field's rule refuses (an email, phone number, date or id in the wrong shape).","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing, expired, revoked, or invalid bearer token.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Token scope or token owner permissions do not allow this request.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Record (or a linked record) not found in this workspace.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate, stale expected_updated_at, or an Idempotency-Key reused with a different body.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded: the key's own limit, the person's combined limit for all their keys and connections, the workspace's combined limit for all its keys, a write limit, the failed-auth throttle, or the daily allowance a read shares with customer MCP calls (by default 1,000 a day per person and 10,000 a day per workspace; the index and health do not count). Wait the Retry-After seconds when the header is present.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Unexpected server or database error.","headers":{"x-torch-request-id":{"$ref":"#/components/headers/PrivateApiRequestId"},"x-torch-api-version":{"$ref":"#/components/headers/PrivateApiVersion"},"x-torch-api-deprecated":{"$ref":"#/components/headers/PrivateApiDeprecated"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"tcrm_<prefix>_<secret>"}},"headers":{"PrivateApiRequestId":{"description":"Stable per-request identifier that also appears in the JSON response body as requestId.","schema":{"type":"string","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"}},"PrivateApiVersion":{"description":"Current private API response contract version.","schema":{"type":"string","example":"2026-05-01"}},"PrivateApiDeprecated":{"description":"Whether the current response contract is deprecated.","schema":{"type":"string","enum":["true","false"],"example":"false"}},"RetryAfter":{"description":"Seconds to wait before retrying: sent with a 429 whose limit names its wait (a rate limit's window, a daily allowance's reset).","schema":{"type":"string","example":"3600"}}},"schemas":{"ListResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"type":"object","additionalProperties":true}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"HealthResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"status":{"type":"string","enum":["ok","watch"]},"checkedAt":{"type":"string","format":"date-time"},"workspaceId":{"type":"string","format":"uuid"},"token":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"expiresAt":{"type":["string","null"],"format":"date-time"},"expiresInDays":{"type":["integer","null"]}},"required":["id","name","scopes","expiresAt"]},"owner":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"email":{"type":["string","null"]},"accessLevel":{"type":["string","null"]}}},"limits":{"type":"object","properties":{"requestWindowMs":{"type":"integer"},"requestLimit":{"type":"integer"},"workspaceRequestWindowMs":{"type":"integer"},"workspaceRequestLimit":{"type":"integer"},"userRequestWindowMs":{"type":"integer"},"userRequestLimit":{"type":"integer"},"failedAuthWindowMs":{"type":"integer"},"failedAuthLimit":{"type":"integer"},"dailyWindowMs":{"type":"integer"},"dailyLimitPerPerson":{"type":"integer"},"dailyLimitPerWorkspace":{"type":"integer"},"dailyLimitSharedBy":{"type":"string"},"mode":{"type":"string"}}},"alerts":{"description":"This key's alert check: the evaluation, or ok false with an error when it could not run.","type":"object","properties":{"ok":{"type":"boolean"},"evaluatedAt":{"type":"string","format":"date-time"},"failureCount":{"type":"integer"},"slowCount":{"type":"integer"},"alertCount":{"type":"integer"},"alerts":{"type":"array","items":{"type":"object"}},"error":{"type":"string"}},"required":["ok"]},"activity":{"type":"object","properties":{"durationAvailable":{"type":"boolean"},"slowRequestMs":{"type":"integer"},"sampleSize":{"type":"integer"},"failureCount":{"type":"integer"},"slowCount":{"type":"integer"},"lastFailure":{"type":["object","null"],"properties":{"id":{"type":"string"},"method":{"type":["string","null"]},"path":{"type":["string","null"]},"status_code":{"type":["integer","null"]},"duration_ms":{"type":["integer","null"]},"created_at":{"type":["string","null"],"format":"date-time"}}},"lastSlowRequest":{"type":["object","null"],"properties":{"id":{"type":"string"},"method":{"type":["string","null"]},"path":{"type":["string","null"]},"status_code":{"type":["integer","null"]},"duration_ms":{"type":["integer","null"]},"created_at":{"type":["string","null"],"format":"date-time"}}},"recent":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"method":{"type":["string","null"]},"path":{"type":["string","null"]},"status_code":{"type":["integer","null"]},"duration_ms":{"type":["integer","null"]},"created_at":{"type":["string","null"],"format":"date-time"}}}}}}},"required":["ok","status","checkedAt","workspaceId","token","activity","requestId","apiVersion","deprecated"]},"DetailResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"object","additionalProperties":true}},"required":["ok","data","requestId","apiVersion","deprecated"]},"SearchResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["ok","data","requestId","apiVersion","deprecated"]},"Pagination":{"type":"object","properties":{"page":{"type":"integer","example":1},"pageSize":{"type":"integer","example":50},"total":{"type":"integer","example":125},"totalPages":{"type":"integer","example":3},"hasNextPage":{"type":"boolean","example":true},"hasPreviousPage":{"type":"boolean","example":false}},"required":["page","pageSize","total","totalPages","hasNextPage","hasPreviousPage"]},"SyncMetadata":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string"}},"includes":{"type":"array","items":{"type":"string"},"description":"The includes embedded on this page (the include parameter's names, in order); empty when none was sent or the list takes none."},"updatedSince":{"type":["string","null"],"format":"date-time"},"createdSince":{"type":["string","null"],"format":"date-time"},"nextCursor":{"type":["string","null"]}}},"ErrorResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":false},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"error":{"type":"string"},"code":{"type":"string","description":"Stable machine-readable error code for retry and support handling. Known codes include invalid_request, unauthorized, payment_required, forbidden, not_found, conflict, gone, payload_too_large, unprocessable, precondition_required, rate_limited, service_unavailable, internal_error, duplicate, constraint, cascade_outside_visibility, restore_outside_visibility, restore_cascade, restore_expired, not_linked, invalid_owner, opportunity_follows_quotes, invalid_if_match, if_match_mismatch, erp_managed, stock_change, source_locked, manufacturer_deleted, duplicate_source, duplicate_reference_code, paid_locked, not_available_yet, lost_reason_required, assignee_inactive, already_converted, company_required, link_deleted, soft_delete_unavailable, parent_loop, duplicate_prevention, deleted_key_holder, cascade_required, approval_required, audit_failed, quote_has_sale, order_not_submitted, historical_sale, too_many_lines, too_many_balances, stock_stale, stock_over_issue, stock_read_only, stock_not_ready, stock_location_not_linked, stock_invalid, stock_out_of_range, over_allocated, order_draft_stage, won_on_create, unpriced_lines, rule_violation, order_not_supported, total_follows_lines, invalid_link; new ones may appear.","example":"forbidden"},"count":{"type":"integer","minimum":1,"description":"Only with cascade_outside_visibility and restore_outside_visibility: how many records the token owner cannot see."},"duplicate_candidates":{"type":"array","maxItems":5,"description":"Only with duplicate_prevention: up to 5 of the matching records the token can read, the strongest match first.","items":{"type":"object","additionalProperties":false,"required":["id","name","match"],"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"],"description":"A company's name; a product's manufacturer and part number."},"match":{"type":"string","description":"How it matched: a company by the same name or a similar phone; a product by the same manufacturer and part number, exactly (any case) or in other formatting."}}}}},"required":["ok","error","code","requestId","apiVersion","deprecated"]},"AccountCreate":{"type":"object","additionalProperties":false,"properties":{"account_name":{"type":"string","maxLength":200,"description":"The company's name (a rename follows onto its quotes, activities, contacts, sales and commissions). Required on create and never blank."},"account_status":{"type":["string","null"],"maxLength":200,"description":"Status, as text (Active, Prospect, Inactive, ...)."},"primary_phone":{"type":["string","null"],"maxLength":40,"description":"Main phone number. A new or changed number must be a phone number: a US or Canadian number (10 digits, or 1 and 10 digits) or an international number starting with +."},"street_address":{"type":["string","null"],"maxLength":200,"description":"Street address."},"street_address_2":{"type":["string","null"],"maxLength":200,"description":"Street address, second line."},"city":{"type":["string","null"],"maxLength":200,"description":"City."},"state":{"type":["string","null"],"maxLength":200,"description":"State or region."},"zip_code":{"type":["string","null"],"maxLength":20,"description":"Postal code."},"territory":{"type":["string","null"],"maxLength":200,"description":"The company's territory, as the app types it (the territory code follows it unless territory_code is sent too). The company must stay inside the token owner's territories (its account manager or creator arm aside); moving it also moves its sales, which needs sales edit and every moved sale in the owner's sales scope."},"territory_code":{"type":["string","null"],"maxLength":200,"description":"The territory's code. On create, a territory-restricted owner sends it only together with territory (else 400); on an update it is kept as sent, and the company must stay inside the owner's territories (403)."},"zone":{"type":["string","null"],"maxLength":200,"description":"Zone."},"mfg_int":{"type":["string","null"],"maxLength":200,"description":"Manufacturer interest, as text."},"account_manager":{"type":["string","null"],"maxLength":200,"description":"The company's account manager, as the app shows it (a name, email or user id: free text). A member's key may leave it blank or set its owner, never another active member (403); with the workspace's account-manager auto-fill on, the company's sales, quotes and commissions follow it."},"type":{"type":["string","null"],"maxLength":200,"description":"Company type."},"parent_account_id":{"type":["string","null"],"format":"uuid","description":"The parent company (a branch's head office); null detaches it. A company the token's owner can read and edit (else 404 Linked record not found, or 403), never the company itself or one of its own descendants (422 parent_loop)."},"is_master_account":{"type":"boolean","description":"Whether the company is a master account."},"ship_to_name":{"type":["string","null"],"maxLength":200,"description":"Ship-to name."},"ship_to_attention":{"type":["string","null"],"maxLength":200,"description":"Ship-to attention line."},"ship_to_street_address":{"type":["string","null"],"maxLength":200,"description":"Ship-to street address."},"ship_to_city":{"type":["string","null"],"maxLength":200,"description":"Ship-to city."},"ship_to_state":{"type":["string","null"],"maxLength":200,"description":"Ship-to state or region."},"ship_to_zip_code":{"type":["string","null"],"maxLength":20,"description":"Ship-to postal code."},"ship_to_country":{"type":["string","null"],"maxLength":200,"description":"Ship-to country."}},"required":["account_name"]},"AccountPatch":{"type":"object","additionalProperties":false,"properties":{"account_name":{"type":"string","maxLength":200,"description":"The company's name (a rename follows onto its quotes, activities, contacts, sales and commissions). Required on create and never blank."},"account_status":{"type":["string","null"],"maxLength":200,"description":"Status, as text (Active, Prospect, Inactive, ...)."},"primary_phone":{"type":["string","null"],"maxLength":40,"description":"Main phone number. A new or changed number must be a phone number: a US or Canadian number (10 digits, or 1 and 10 digits) or an international number starting with +."},"street_address":{"type":["string","null"],"maxLength":200,"description":"Street address."},"street_address_2":{"type":["string","null"],"maxLength":200,"description":"Street address, second line."},"city":{"type":["string","null"],"maxLength":200,"description":"City."},"state":{"type":["string","null"],"maxLength":200,"description":"State or region."},"zip_code":{"type":["string","null"],"maxLength":20,"description":"Postal code."},"territory":{"type":["string","null"],"maxLength":200,"description":"The company's territory, as the app types it (the territory code follows it unless territory_code is sent too). The company must stay inside the token owner's territories (its account manager or creator arm aside); moving it also moves its sales, which needs sales edit and every moved sale in the owner's sales scope."},"territory_code":{"type":["string","null"],"maxLength":200,"description":"The territory's code. On create, a territory-restricted owner sends it only together with territory (else 400); on an update it is kept as sent, and the company must stay inside the owner's territories (403)."},"zone":{"type":["string","null"],"maxLength":200,"description":"Zone."},"mfg_int":{"type":["string","null"],"maxLength":200,"description":"Manufacturer interest, as text."},"account_manager":{"type":["string","null"],"maxLength":200,"description":"The company's account manager, as the app shows it (a name, email or user id: free text). A member's key may leave it blank or set its owner, never another active member (403); with the workspace's account-manager auto-fill on, the company's sales, quotes and commissions follow it."},"type":{"type":["string","null"],"maxLength":200,"description":"Company type."},"parent_account_id":{"type":["string","null"],"format":"uuid","description":"The parent company (a branch's head office); null detaches it. A company the token's owner can read and edit (else 404 Linked record not found, or 403), never the company itself or one of its own descendants (422 parent_loop)."},"is_master_account":{"type":"boolean","description":"Whether the company is a master account."},"ship_to_name":{"type":["string","null"],"maxLength":200,"description":"Ship-to name."},"ship_to_attention":{"type":["string","null"],"maxLength":200,"description":"Ship-to attention line."},"ship_to_street_address":{"type":["string","null"],"maxLength":200,"description":"Ship-to street address."},"ship_to_city":{"type":["string","null"],"maxLength":200,"description":"Ship-to city."},"ship_to_state":{"type":["string","null"],"maxLength":200,"description":"Ship-to state or region."},"ship_to_zip_code":{"type":["string","null"],"maxLength":20,"description":"Ship-to postal code."},"ship_to_country":{"type":["string","null"],"maxLength":200,"description":"Ship-to country."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"ContactCreate":{"type":"object","additionalProperties":false,"properties":{"first_name":{"type":["string","null"],"maxLength":200,"description":"First name."},"last_name":{"type":["string","null"],"maxLength":200,"description":"Last name."},"company_name":{"type":["string","null"],"maxLength":200,"description":"Company name as text."},"phone":{"type":["string","null"],"maxLength":40,"description":"Phone number. A US or Canadian number (10 digits, or 1 and 10 digits) or an international number starting with +. Any other new or changed value (letters, an extension, a 7-digit local number) is a 400; the contact's own stored number sent back unchanged is accepted and left as stored."},"title":{"type":["string","null"],"maxLength":200,"description":"Job title."},"address":{"type":["string","null"],"maxLength":500,"description":"Street address."},"city":{"type":["string","null"],"maxLength":200,"description":"City."},"state":{"type":["string","null"],"maxLength":200,"description":"State or region."},"zip_code":{"type":["string","null"],"maxLength":20,"description":"Postal code."},"full_name":{"type":["string","null"],"maxLength":400,"description":"Split into first_name / last_name when those are absent."},"email":{"type":["string","null"],"maxLength":320,"format":"email","description":"Email address. A write takes name@domain.tld: any other new or changed value is a 400; the contact's own stored email sent back unchanged is accepted when it has the name@domain shape."},"tags":{"type":["array","null"],"items":{"type":"string","maxLength":100},"maxItems":50,"description":"Up to 50 tags, deduplicated."}}},"ContactPatch":{"type":"object","additionalProperties":false,"properties":{"first_name":{"type":["string","null"],"maxLength":200,"description":"First name."},"last_name":{"type":["string","null"],"maxLength":200,"description":"Last name."},"company_name":{"type":["string","null"],"maxLength":200,"description":"Company name as text."},"phone":{"type":["string","null"],"maxLength":40,"description":"Phone number. A US or Canadian number (10 digits, or 1 and 10 digits) or an international number starting with +. Any other new or changed value (letters, an extension, a 7-digit local number) is a 400; the contact's own stored number sent back unchanged is accepted and left as stored."},"title":{"type":["string","null"],"maxLength":200,"description":"Job title."},"address":{"type":["string","null"],"maxLength":500,"description":"Street address."},"city":{"type":["string","null"],"maxLength":200,"description":"City."},"state":{"type":["string","null"],"maxLength":200,"description":"State or region."},"zip_code":{"type":["string","null"],"maxLength":20,"description":"Postal code."},"full_name":{"type":["string","null"],"maxLength":400,"description":"Split into first_name / last_name when those are absent."},"email":{"type":["string","null"],"maxLength":320,"format":"email","description":"Email address. A write takes name@domain.tld: any other new or changed value is a 400; the contact's own stored email sent back unchanged is accepted when it has the name@domain shape."},"tags":{"type":["array","null"],"items":{"type":"string","maxLength":100},"maxItems":50,"description":"Up to 50 tags, deduplicated."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"ActivityCreate":{"type":"object","additionalProperties":false,"properties":{"type":{"type":["string","null"],"maxLength":80,"description":"Activity type, e.g. Call, Email, Meeting, Task, Note. Defaults to Task."},"subject":{"type":["string","null"],"maxLength":200,"description":"Subject line."},"activity_name":{"type":["string","null"],"maxLength":200,"description":"Activity name."},"description":{"type":["string","null"],"maxLength":10000,"description":"Notes, as plain text (newlines kept)."},"account":{"type":["string","null"],"maxLength":200,"description":"Company name as text."},"contact":{"type":["string","null"],"maxLength":200,"description":"Contact name as text."},"manufacturer":{"type":["string","null"],"maxLength":200,"description":"Manufacturer name as text."},"end_user":{"type":["string","null"],"maxLength":200,"description":"End user name."},"end_user_contact":{"type":["string","null"],"maxLength":200,"description":"End user contact name."},"manufacturer_contact":{"type":["string","null"],"maxLength":200,"description":"Manufacturer contact name."},"assigned_to":{"type":["string","null"],"format":"uuid","description":"A user id in the token's workspace."},"account_id":{"type":["string","null"],"format":"uuid","description":"The linked company."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The linked contact."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The linked manufacturer."},"quote_id":{"type":["string","null"],"format":"uuid","description":"The linked quote."},"sale_id":{"type":["string","null"],"format":"uuid","description":"The linked sale."},"activity_date":{"type":["string","null"],"maxLength":40,"description":"ISO 8601 date or timestamp."},"due_date":{"type":["string","null"],"maxLength":40,"description":"ISO 8601 date or timestamp."},"reminder_at":{"type":["string","null"],"maxLength":40,"description":"ISO 8601 date or timestamp."}}},"ActivityPatch":{"type":"object","additionalProperties":false,"properties":{"type":{"type":["string","null"],"maxLength":80,"description":"Activity type, e.g. Call, Email, Meeting, Task, Note. Defaults to Task."},"subject":{"type":["string","null"],"maxLength":200,"description":"Subject line."},"activity_name":{"type":["string","null"],"maxLength":200,"description":"Activity name."},"description":{"type":["string","null"],"maxLength":10000,"description":"Notes, as plain text (newlines kept)."},"account":{"type":["string","null"],"maxLength":200,"description":"Company name as text."},"contact":{"type":["string","null"],"maxLength":200,"description":"Contact name as text."},"manufacturer":{"type":["string","null"],"maxLength":200,"description":"Manufacturer name as text."},"end_user":{"type":["string","null"],"maxLength":200,"description":"End user name."},"end_user_contact":{"type":["string","null"],"maxLength":200,"description":"End user contact name."},"manufacturer_contact":{"type":["string","null"],"maxLength":200,"description":"Manufacturer contact name."},"assigned_to":{"type":["string","null"],"format":"uuid","description":"A user id in the token's workspace."},"account_id":{"type":["string","null"],"format":"uuid","description":"The linked company."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The linked contact."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The linked manufacturer."},"quote_id":{"type":["string","null"],"format":"uuid","description":"The linked quote."},"sale_id":{"type":["string","null"],"format":"uuid","description":"The linked sale."},"activity_date":{"type":["string","null"],"maxLength":40,"description":"ISO 8601 date or timestamp."},"due_date":{"type":["string","null"],"maxLength":40,"description":"ISO 8601 date or timestamp."},"reminder_at":{"type":["string","null"],"maxLength":40,"description":"ISO 8601 date or timestamp."},"completed":{"type":"boolean","description":"Whether the activity is done; empty (null) counts as not done in the app."},"priority":{"type":["string","null"],"enum":["low","medium","high",null],"description":"low, medium or high (any case); empty clears it, and an empty priority (null) counts as medium in the app."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"Compared with the record's updated_at, which does not move on every change to this record yet, so it does not detect every concurrent edit."}}},"ManufacturerCreate":{"type":"object","additionalProperties":false,"properties":{"manufacturer_name":{"type":"string","maxLength":200,"description":"The manufacturer's name, unique in the workspace (a rename follows onto its quotes, sales, activities, commissions, products, inventory and the opportunities' principal lists). One name: a semicolon, a vertical bar or a line break in it is a 400 (the territory / manufacturer scope reads them as separators between names), and a name another manufacturer in the workspace has ignoring case, a soft-deleted one included, is a 409."},"terms_and_conditions":{"type":["string","null"],"maxLength":10000,"description":"Terms and conditions, as plain text (newlines kept)."},"mfg_territory":{"type":["string","null"],"maxLength":200,"description":"The territory the manufacturer belongs to; it must stay inside the token owner's territories."},"expected_sales":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":0,"maximum":1000000000000,"description":"Expected annual sales."},"primary_phone":{"type":["string","null"],"maxLength":40,"description":"Main phone number."},"city":{"type":["string","null"],"maxLength":200,"description":"City."},"state":{"type":["string","null"],"maxLength":200,"description":"State or region."},"zip_code":{"type":["string","null"],"maxLength":20,"description":"Postal code."},"regional_manager":{"type":["string","null"],"maxLength":200,"description":"The manufacturer's regional manager, as text."}},"required":["manufacturer_name"]},"ManufacturerPatch":{"type":"object","additionalProperties":false,"properties":{"manufacturer_name":{"type":"string","maxLength":200,"description":"The manufacturer's name, unique in the workspace (a rename follows onto its quotes, sales, activities, commissions, products, inventory and the opportunities' principal lists). One name: a semicolon, a vertical bar or a line break in it is a 400 (the territory / manufacturer scope reads them as separators between names), and a name another manufacturer in the workspace has ignoring case, a soft-deleted one included, is a 409."},"terms_and_conditions":{"type":["string","null"],"maxLength":10000,"description":"Terms and conditions, as plain text (newlines kept)."},"mfg_territory":{"type":["string","null"],"maxLength":200,"description":"The territory the manufacturer belongs to; it must stay inside the token owner's territories."},"expected_sales":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":0,"maximum":1000000000000,"description":"Expected annual sales."},"primary_phone":{"type":["string","null"],"maxLength":40,"description":"Main phone number."},"city":{"type":["string","null"],"maxLength":200,"description":"City."},"state":{"type":["string","null"],"maxLength":200,"description":"State or region."},"zip_code":{"type":["string","null"],"maxLength":20,"description":"Postal code."},"regional_manager":{"type":["string","null"],"maxLength":200,"description":"The manufacturer's regional manager, as text."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"ProductCreate":{"type":"object","additionalProperties":false,"properties":{"stock":{"type":["boolean","null"],"description":"Whether the product is a stocked item. true, false or null."},"manufacturer_name":{"type":"string","maxLength":200,"description":"The manufacturer's name as text: with part_number, the product's catalog key in the workspace, and what a token owner limited to some manufacturers is matched by. Required on create, never empty; one name (no semicolon, vertical bar or line break). The product must stay inside the token owner's manufacturer scope (403 otherwise)."},"part_number":{"type":"string","maxLength":200,"description":"Part number: with manufacturer_name, the product's catalog key in the workspace. Required on create, never empty."},"product_family":{"type":["string","null"],"maxLength":200,"description":"Product family."},"product_line":{"type":["string","null"],"maxLength":200,"description":"Product line."},"root_part_no":{"type":["string","null"],"maxLength":200,"description":"Root part number."},"list_price":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":9999999999,"description":"List price. A number (or decimal text) from 0, at most 4 decimal places. Setting it (create) or changing it (update) needs the token owner's Edit pricing ability (403 otherwise); null sets no price."},"stock_price":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":9999999999,"description":"Stock price. A number (or decimal text) from 0, at most 4 decimal places. Setting it (create) or changing it (update) needs the token owner's Edit pricing ability (403 otherwise); null sets no price."},"commission_rate":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,6})?$","minimum":0,"maximum":1,"description":"Commission rate as a fraction (0.08 = 8%). A number (or decimal text) from 0 to 1, at most 6 decimal places (0.08 = 8%; \"8%\" is refused). Setting it (create) or changing it (update) needs the token owner's Edit pricing ability (403 otherwise); null sets no price."},"lead_time":{"type":["string","null"],"maxLength":200,"description":"Lead time as text."},"upc":{"type":["string","null"],"maxLength":200,"description":"UPC code."},"uom":{"type":["string","null"],"maxLength":50,"description":"Unit of measure."},"hou_stock":{"type":["integer","null"],"minimum":0,"maximum":2147483647,"description":"Stock on hand in the first location stock column. Usually 0 or empty in a workspace that does not record stock here. A whole number from 0, or null."},"pharr_stock":{"type":["integer","null"],"minimum":0,"maximum":2147483647,"description":"Stock on hand in the second location stock column. Usually 0 or empty in a workspace that does not record stock here. A whole number from 0, or null."},"reorder_level":{"type":["integer","null"],"minimum":0,"maximum":2147483647,"description":"Reorder level. A whole number from 0, or null."},"shipping_weight":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":1000000,"description":"Shipping weight. A number (or decimal text) from 0 to 1,000,000, at most 4 decimal places, or null."},"unit_cost":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":9999999999,"description":"Unit cost. Returned only to a token whose owner is an admin or a manager (has reports). Only for a token whose owner is an admin or a manager (for any other owner it is an unknown field: 400). A number (or decimal text) from 0, at most 4 decimal places. Setting it (create) or changing it (update) needs the token owner's Edit pricing ability (403 otherwise); null sets no price."},"description":{"type":["string","null"],"maxLength":2000,"description":"Description."},"price_code":{"type":["string","null"],"maxLength":50,"description":"Price code. Compared as text: \"a\" is a change from \"A\". Setting it (create) or changing it (update) needs the token owner's Edit pricing ability (403 otherwise); null sets no price."},"image_url":{"type":["string","null"],"maxLength":2000,"format":"uri","description":"Image link (http or https)."},"specification_url":{"type":["string","null"],"maxLength":2000,"format":"uri","description":"Specification sheet link (http or https)."},"notes":{"type":["string","null"],"maxLength":10000,"description":"Notes."}},"required":["manufacturer_name","part_number"]},"ProductPatch":{"type":"object","additionalProperties":false,"properties":{"stock":{"type":["boolean","null"],"description":"Whether the product is a stocked item. true, false or null."},"manufacturer_name":{"type":"string","maxLength":200,"description":"The manufacturer's name as text: with part_number, the product's catalog key in the workspace, and what a token owner limited to some manufacturers is matched by. Required on create, never empty; one name (no semicolon, vertical bar or line break). The product must stay inside the token owner's manufacturer scope (403 otherwise)."},"part_number":{"type":"string","maxLength":200,"description":"Part number: with manufacturer_name, the product's catalog key in the workspace. Required on create, never empty."},"product_family":{"type":["string","null"],"maxLength":200,"description":"Product family."},"product_line":{"type":["string","null"],"maxLength":200,"description":"Product line."},"root_part_no":{"type":["string","null"],"maxLength":200,"description":"Root part number."},"list_price":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":9999999999,"description":"List price. A number (or decimal text) from 0, at most 4 decimal places. Setting it (create) or changing it (update) needs the token owner's Edit pricing ability (403 otherwise); null sets no price."},"stock_price":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":9999999999,"description":"Stock price. A number (or decimal text) from 0, at most 4 decimal places. Setting it (create) or changing it (update) needs the token owner's Edit pricing ability (403 otherwise); null sets no price."},"commission_rate":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,6})?$","minimum":0,"maximum":1,"description":"Commission rate as a fraction (0.08 = 8%). A number (or decimal text) from 0 to 1, at most 6 decimal places (0.08 = 8%; \"8%\" is refused). Setting it (create) or changing it (update) needs the token owner's Edit pricing ability (403 otherwise); null sets no price."},"lead_time":{"type":["string","null"],"maxLength":200,"description":"Lead time as text."},"upc":{"type":["string","null"],"maxLength":200,"description":"UPC code."},"uom":{"type":["string","null"],"maxLength":50,"description":"Unit of measure."},"hou_stock":{"type":["integer","null"],"minimum":0,"maximum":2147483647,"description":"Stock on hand in the first location stock column. Usually 0 or empty in a workspace that does not record stock here. A whole number from 0, or null."},"pharr_stock":{"type":["integer","null"],"minimum":0,"maximum":2147483647,"description":"Stock on hand in the second location stock column. Usually 0 or empty in a workspace that does not record stock here. A whole number from 0, or null."},"reorder_level":{"type":["integer","null"],"minimum":0,"maximum":2147483647,"description":"Reorder level. A whole number from 0, or null."},"shipping_weight":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":1000000,"description":"Shipping weight. A number (or decimal text) from 0 to 1,000,000, at most 4 decimal places, or null."},"unit_cost":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":9999999999,"description":"Unit cost. Returned only to a token whose owner is an admin or a manager (has reports). Only for a token whose owner is an admin or a manager (for any other owner it is an unknown field: 400). A number (or decimal text) from 0, at most 4 decimal places. Setting it (create) or changing it (update) needs the token owner's Edit pricing ability (403 otherwise); null sets no price."},"description":{"type":["string","null"],"maxLength":2000,"description":"Description."},"price_code":{"type":["string","null"],"maxLength":50,"description":"Price code. Compared as text: \"a\" is a change from \"A\". Setting it (create) or changing it (update) needs the token owner's Edit pricing ability (403 otherwise); null sets no price."},"image_url":{"type":["string","null"],"maxLength":2000,"format":"uri","description":"Image link (http or https)."},"specification_url":{"type":["string","null"],"maxLength":2000,"format":"uri","description":"Specification sheet link (http or https)."},"notes":{"type":["string","null"],"maxLength":10000,"description":"Notes."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"LeadCreate":{"type":"object","additionalProperties":false,"properties":{"company":{"type":["string","null"],"maxLength":200,"description":"The company the lead is for. Defaults to an empty string; null stores an empty string."},"contact_name":{"type":["string","null"],"maxLength":200,"description":"The person at the company."},"title":{"type":["string","null"],"maxLength":200,"description":"Their job title."},"email":{"type":["string","null"],"maxLength":320,"format":"email","description":"Their email address."},"phone":{"type":["string","null"],"maxLength":50,"description":"Their phone number."},"source":{"type":["string","null"],"maxLength":120,"description":"Where the lead came from (Website, Trade Show, Referral, ...)."},"status":{"type":"string","enum":["New","Attempting Contact","Qualified","Quoted","Lost","Disqualified","No Response"],"description":"Where the lead stands. Defaults to New. Converted is set only by POST /api/v1/leads/{id}/convert."},"priority":{"type":"string","enum":["Hot","Warm","Cold"],"description":"Hot, Warm or Cold. Defaults to Warm."},"assigned_to":{"type":["string","null"],"format":"uuid","description":"The user who owns the lead (a user id in the token's workspace). Empty unless set. An active user of the workspace (else 404 Linked record not found, or 422 assignee_inactive); a member's token may not assign a lead to another member (403)."},"territory":{"type":["string","null"],"maxLength":120,"description":"The lead's territory, as text (a territory code or name). The lead must stay inside the token owner's lead scope (403)."},"manufacturer_interest":{"type":["string","null"],"maxLength":1000,"description":"The manufacturers the lead is interested in, as text (names separated by semicolons)."},"account_id":{"type":["string","null"],"format":"uuid","description":"The company record the lead is linked to. One the token's owner can read (else 404 Linked record not found). null unlinks."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The lead's primary contact record. One the token's owner can read (else 404 Linked record not found). null unlinks."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer record the lead is linked to. One the token's owner can read (else 404 Linked record not found). null unlinks."},"next_follow_up":{"type":["string","null"],"maxLength":40,"description":"The next follow-up date (YYYY-MM-DD)."},"estimated_value":{"type":["number","string"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":0,"maximum":9999999999.99,"description":"The lead's estimated value. Defaults to 0."},"notes":{"type":["string","null"],"maxLength":10000,"description":"Notes, as plain text."},"lost_reason":{"type":["string","null"],"maxLength":200,"description":"Why the lead was lost. Write-only: never stored on the lead or returned (it is recorded on the lead's timeline). Required (422 lost_reason_required) when the write moves the lead into Lost while lost reasons are on in the workspace's app."}}},"LeadPatch":{"type":"object","additionalProperties":false,"properties":{"company":{"type":["string","null"],"maxLength":200,"description":"The company the lead is for. Defaults to an empty string; null stores an empty string."},"contact_name":{"type":["string","null"],"maxLength":200,"description":"The person at the company."},"title":{"type":["string","null"],"maxLength":200,"description":"Their job title."},"email":{"type":["string","null"],"maxLength":320,"format":"email","description":"Their email address."},"phone":{"type":["string","null"],"maxLength":50,"description":"Their phone number."},"source":{"type":["string","null"],"maxLength":120,"description":"Where the lead came from (Website, Trade Show, Referral, ...)."},"status":{"type":"string","enum":["New","Attempting Contact","Qualified","Quoted","Lost","Disqualified","No Response"],"description":"Where the lead stands. Defaults to New. Converted is set only by POST /api/v1/leads/{id}/convert."},"priority":{"type":"string","enum":["Hot","Warm","Cold"],"description":"Hot, Warm or Cold. Defaults to Warm."},"assigned_to":{"type":["string","null"],"format":"uuid","description":"The user who owns the lead (a user id in the token's workspace). Empty unless set. An active user of the workspace (else 404 Linked record not found, or 422 assignee_inactive); a member's token may not assign a lead to another member (403)."},"territory":{"type":["string","null"],"maxLength":120,"description":"The lead's territory, as text (a territory code or name). The lead must stay inside the token owner's lead scope (403)."},"manufacturer_interest":{"type":["string","null"],"maxLength":1000,"description":"The manufacturers the lead is interested in, as text (names separated by semicolons)."},"account_id":{"type":["string","null"],"format":"uuid","description":"The company record the lead is linked to. One the token's owner can read (else 404 Linked record not found). null unlinks."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The lead's primary contact record. One the token's owner can read (else 404 Linked record not found). null unlinks."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer record the lead is linked to. One the token's owner can read (else 404 Linked record not found). null unlinks."},"next_follow_up":{"type":["string","null"],"maxLength":40,"description":"The next follow-up date (YYYY-MM-DD)."},"estimated_value":{"type":["number","string"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":0,"maximum":9999999999.99,"description":"The lead's estimated value. Defaults to 0."},"notes":{"type":["string","null"],"maxLength":10000,"description":"Notes, as plain text."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."},"lost_reason":{"type":["string","null"],"maxLength":200,"description":"Why the lead was lost. Write-only: never stored on the lead or returned (it is recorded on the lead's timeline). Required (422 lost_reason_required) when the write moves the lead into Lost while lost reasons are on in the workspace's app."}}},"InventoryItemCreate":{"type":"object","additionalProperties":false,"properties":{"item_name":{"type":["string","null"],"maxLength":200,"description":"Item name."},"manufacturer":{"type":["string","null"],"maxLength":200,"description":"Manufacturer name as text; must be in the key owner's manufacturer scope when they have one."},"part_number":{"type":["string","null"],"maxLength":200,"description":"Part number."},"description":{"type":["string","null"],"maxLength":2000,"description":"Description."},"houston_stock":{"type":"integer","minimum":0,"maximum":1000000,"description":"Stock on hand, a whole number. Defaults to 0 on create. On an ERP-linked item a change is a count at the ERP's main location and needs expected_houston_stock."},"bin_location":{"type":["string","null"],"maxLength":200,"description":"Bin or shelf location."},"assigned_to":{"type":["string","null"],"maxLength":200,"description":"Who holds the item, as the name the app shows (the own-records lock reads it)."}}},"InventoryItemPatch":{"type":"object","additionalProperties":false,"properties":{"item_name":{"type":["string","null"],"maxLength":200,"description":"Item name."},"manufacturer":{"type":["string","null"],"maxLength":200,"description":"Manufacturer name as text; must be in the key owner's manufacturer scope when they have one."},"part_number":{"type":["string","null"],"maxLength":200,"description":"Part number."},"description":{"type":["string","null"],"maxLength":2000,"description":"Description."},"houston_stock":{"type":"integer","minimum":0,"maximum":1000000,"description":"Stock on hand, a whole number. Defaults to 0 on create. On an ERP-linked item a change is a count at the ERP's main location and needs expected_houston_stock."},"bin_location":{"type":["string","null"],"maxLength":200,"description":"Bin or shelf location."},"assigned_to":{"type":["string","null"],"maxLength":200,"description":"Who holds the item, as the name the app shows (the own-records lock reads it)."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."},"expected_houston_stock":{"type":["integer","null"],"minimum":-2147483648,"maximum":2147483647,"description":"The houston_stock you last read (any whole number the stock column holds: only compared, never written, so a stock past houston_stock's write range is still counted). Needed to change the stock of an item an ERP owns (a count at its main location, refused 409 when the stock moved since); ignored for other items."}}},"SampleCreate":{"type":"object","additionalProperties":false,"properties":{"manufacturer":{"type":["string","null"],"maxLength":200,"description":"Manufacturer name as text."},"part_number":{"type":["string","null"],"maxLength":200,"description":"Part number."},"description":{"type":["string","null"],"maxLength":2000,"description":"Description."},"location":{"type":["string","null"],"maxLength":200,"description":"Where the sample is kept (a city or office)."},"houston_stock":{"type":"integer","minimum":0,"maximum":2147483647,"description":"How many are on hand, a whole number. Defaults to 0 on create."},"bin_location":{"type":["string","null"],"maxLength":200,"description":"Bin or shelf location."},"assigned_to":{"type":["string","null"],"maxLength":200,"description":"Who has the sample checked out, as the name the app shows (free text). Setting it checks the sample out now; clearing it checks it back in."},"workflow_state":{"type":"string","enum":["available","requested","approved","checked_out","returned","lost","damaged"],"description":"Where the sample is in its checkout workflow. lost, damaged, requested and approved are kept as sent; any other state is set from assigned_to (checked_out when someone has it, else available), as the app does."},"linked_account_id":{"type":["string","null"],"format":"uuid","description":"The company the sample is for: one the token's owner can read (else 404 Linked record not found; an owner without accounts read: 403, whatever the id). null unlinks."},"linked_contact_id":{"type":["string","null"],"format":"uuid","description":"The contact the sample is for: one the token's owner can read (else 404 Linked record not found; an owner without contacts read: 403, whatever the id). null unlinks."}}},"SamplePatch":{"type":"object","additionalProperties":false,"properties":{"manufacturer":{"type":["string","null"],"maxLength":200,"description":"Manufacturer name as text."},"part_number":{"type":["string","null"],"maxLength":200,"description":"Part number."},"description":{"type":["string","null"],"maxLength":2000,"description":"Description."},"location":{"type":["string","null"],"maxLength":200,"description":"Where the sample is kept (a city or office)."},"houston_stock":{"type":"integer","minimum":0,"maximum":2147483647,"description":"How many are on hand, a whole number. Defaults to 0 on create."},"bin_location":{"type":["string","null"],"maxLength":200,"description":"Bin or shelf location."},"assigned_to":{"type":["string","null"],"maxLength":200,"description":"Who has the sample checked out, as the name the app shows (free text). Setting it checks the sample out now; clearing it checks it back in."},"workflow_state":{"type":"string","enum":["available","requested","approved","checked_out","returned","lost","damaged"],"description":"Where the sample is in its checkout workflow. lost, damaged, requested and approved are kept as sent; any other state is set from assigned_to (checked_out when someone has it, else available), as the app does."},"linked_account_id":{"type":["string","null"],"format":"uuid","description":"The company the sample is for: one the token's owner can read (else 404 Linked record not found; an owner without accounts read: 403, whatever the id). null unlinks."},"linked_contact_id":{"type":["string","null"],"format":"uuid","description":"The contact the sample is for: one the token's owner can read (else 404 Linked record not found; an owner without contacts read: 403, whatever the id). null unlinks."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"LineSheetCreate":{"type":"object","additionalProperties":false,"properties":{"title":{"type":"string","maxLength":200,"description":"The line sheet's title."},"reference_code":{"type":"string","maxLength":64,"description":"Stored in upper case; any run of characters other than A-Z, 0-9, ., _ and - becomes one -. Made from the title when a create leaves it out. On create a code another sheet in the workspace has gets the next free -2, -3, ... suffix; on update it is a 409."},"description":{"type":["string","null"],"maxLength":2000,"description":"A description, as plain text."},"category":{"type":["string","null"],"maxLength":200,"description":"Category, e.g. Territory Line Sheet, Product Brochure, Stock Sheet."},"product_family":{"type":["string","null"],"maxLength":200,"description":"Product family."},"territory_codes":{"type":["array","null"],"items":{"type":"string","maxLength":100},"maxItems":50,"description":"Territory codes, stored in upper case; an entry holding commas, semicolons or line breaks is split."},"tags":{"type":["array","null"],"items":{"type":"string","maxLength":100},"maxItems":50,"description":"Tags; an entry holding commas, semicolons or line breaks is split."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The linked manufacturer: one in the token's workspace that is not deleted."},"source_url":{"type":"string","maxLength":2000,"format":"uri","pattern":"^[Hh][Tt][Tt][Pp][Ss]://","description":"The web link. Another sheet in the workspace with the same link (ignoring case) is a 409. Sending it makes the sheet a web link; an uploaded sheet's file cannot be replaced through the API (422)."},"active":{"type":"boolean","description":"false archives the sheet (archived_at is stamped); true brings it back. A new sheet is active unless the create says false."},"featured":{"type":"boolean","description":"Whether the sheet is featured. Defaults to false."}},"required":["title","source_url"]},"LineSheetPatch":{"type":"object","additionalProperties":false,"properties":{"title":{"type":"string","maxLength":200,"description":"The line sheet's title."},"reference_code":{"type":"string","maxLength":64,"description":"Stored in upper case; any run of characters other than A-Z, 0-9, ., _ and - becomes one -. Made from the title when a create leaves it out. On create a code another sheet in the workspace has gets the next free -2, -3, ... suffix; on update it is a 409."},"description":{"type":["string","null"],"maxLength":2000,"description":"A description, as plain text."},"category":{"type":["string","null"],"maxLength":200,"description":"Category, e.g. Territory Line Sheet, Product Brochure, Stock Sheet."},"product_family":{"type":["string","null"],"maxLength":200,"description":"Product family."},"territory_codes":{"type":["array","null"],"items":{"type":"string","maxLength":100},"maxItems":50,"description":"Territory codes, stored in upper case; an entry holding commas, semicolons or line breaks is split."},"tags":{"type":["array","null"],"items":{"type":"string","maxLength":100},"maxItems":50,"description":"Tags; an entry holding commas, semicolons or line breaks is split."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The linked manufacturer: one in the token's workspace that is not deleted."},"source_url":{"type":"string","maxLength":2000,"format":"uri","pattern":"^[Hh][Tt][Tt][Pp][Ss]://","description":"The web link. Another sheet in the workspace with the same link (ignoring case) is a 409. Sending it makes the sheet a web link; an uploaded sheet's file cannot be replaced through the API (422)."},"active":{"type":"boolean","description":"false archives the sheet (archived_at is stamped); true brings it back. A new sheet is active unless the create says false."},"featured":{"type":"boolean","description":"Whether the sheet is featured. Defaults to false."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"OpportunityCreate":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","maxLength":200,"description":"The project's name."},"account_id":{"type":["string","null"],"format":"uuid","description":"The project's company (a company id in the token's workspace), or null."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The project's contact (a contact id the key can read), or null."},"manufacturers":{"type":["array","null"],"items":{"type":"string","maxLength":200},"maxItems":25,"description":"Manufacturer names the project is for (deduplicated); they decide its manufacturer scope."},"estimated_value":{"type":["number","string"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":0,"maximum":999999999999.99,"description":"The estimate, in the workspace currency. Counted in the pipeline until a quote is linked."},"stage":{"type":["string","null"],"maxLength":80,"description":"The stage, as configured in the workspace's project stages."},"win_probability":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":0,"maximum":100,"description":"Win % (0 to 100), or null to follow the stage's percent."},"expected_close":{"type":["string","null"],"maxLength":10,"description":"Expected close date, YYYY-MM-DD."},"owner_user_id":{"type":["string","null"],"format":"uuid","description":"The owner (an active user in the token's workspace). A create without one is owned by the key's owner."},"source":{"type":["string","null"],"maxLength":120,"description":"Where the project came from."},"next_step":{"type":["string","null"],"maxLength":500,"description":"The next step."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."},"lost_reason":{"type":["string","null"],"maxLength":200,"description":"Why it was lost; kept only on a move into a Lost stage, cleared on any other stage."},"lost_competitor":{"type":["string","null"],"maxLength":200,"description":"Who it was lost to; kept only with a Lost stage, like lost_reason."}},"required":["name"]},"OpportunityPatch":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","maxLength":200,"description":"The project's name."},"account_id":{"type":["string","null"],"format":"uuid","description":"The project's company (a company id in the token's workspace), or null."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The project's contact (a contact id the key can read), or null."},"manufacturers":{"type":["array","null"],"items":{"type":"string","maxLength":200},"maxItems":25,"description":"Manufacturer names the project is for (deduplicated); they decide its manufacturer scope."},"estimated_value":{"type":["number","string"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":0,"maximum":999999999999.99,"description":"The estimate, in the workspace currency. Counted in the pipeline until a quote is linked."},"stage":{"type":["string","null"],"maxLength":80,"description":"The stage, as configured in the workspace's project stages."},"win_probability":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":0,"maximum":100,"description":"Win % (0 to 100), or null to follow the stage's percent."},"expected_close":{"type":["string","null"],"maxLength":10,"description":"Expected close date, YYYY-MM-DD."},"owner_user_id":{"type":["string","null"],"format":"uuid","description":"The owner (an active user in the token's workspace). A create without one is owned by the key's owner."},"source":{"type":["string","null"],"maxLength":120,"description":"Where the project came from."},"next_step":{"type":["string","null"],"maxLength":500,"description":"The next step."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."},"lost_reason":{"type":["string","null"],"maxLength":200,"description":"Why it was lost; kept only on a move into a Lost stage, cleared on any other stage."},"lost_competitor":{"type":["string","null"],"maxLength":200,"description":"Who it was lost to; kept only with a Lost stage, like lost_reason."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"DeleteResult":{"type":"object","additionalProperties":false,"properties":{"ok":{"type":"boolean","const":true},"data":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true},"deleted_at":{"type":"string","format":"date-time"},"restorable_until":{"type":"string","format":"date-time"},"restore":{"type":"string","enum":["deleter","admin"]},"deleted_accounts":{"type":"integer","minimum":1}},"required":["id","deleted","deleted_at","restorable_until","restore"]},"warning":{"type":"string","enum":["detach_incomplete"]},"replayed":{"type":"boolean"},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false}},"required":["ok","data","requestId","apiVersion","deprecated"]},"PriceSheetCreate":{"type":"object","additionalProperties":false,"properties":{"distributor_account_id":{"type":["string","null"],"format":"uuid","description":"The distributor company (blank: the manufacturer's base list book). A company of this workspace that GET /api/v1/accounts/{id} shows the token's owner (404 Linked record not found otherwise); checked when set or changed."},"distributor":{"type":["string","null"],"maxLength":500,"description":"The distributor's name as entered."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer. A live manufacturer of this workspace inside the owner's manufacturers read scope (404 Linked record not found otherwise); checked when set or changed."},"manufacturer":{"type":["string","null"],"maxLength":500,"description":"The manufacturer's name as entered (a sheet needs a manufacturer: 422 otherwise)."},"name":{"type":["string","null"],"maxLength":500,"description":"The sheet's name."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."}}},"PriceSheetPatch":{"type":"object","additionalProperties":false,"properties":{"distributor_account_id":{"type":["string","null"],"format":"uuid","description":"The distributor company (blank: the manufacturer's base list book). A company of this workspace that GET /api/v1/accounts/{id} shows the token's owner (404 Linked record not found otherwise); checked when set or changed."},"distributor":{"type":["string","null"],"maxLength":500,"description":"The distributor's name as entered."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer. A live manufacturer of this workspace inside the owner's manufacturers read scope (404 Linked record not found otherwise); checked when set or changed."},"manufacturer":{"type":["string","null"],"maxLength":500,"description":"The manufacturer's name as entered (a sheet needs a manufacturer: 422 otherwise)."},"name":{"type":["string","null"],"maxLength":500,"description":"The sheet's name."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"PriceSheetRowCreate":{"type":"object","additionalProperties":false,"properties":{"price_sheet_id":{"type":"string","format":"uuid","description":"The price sheet the row is on. A price sheet of this workspace (404 Linked record not found otherwise)."},"manufacturer":{"type":["string","null"],"maxLength":500,"description":"The manufacturer as the imported file named it (descriptive only: the sheet is authoritative)."},"part_number":{"type":"string","maxLength":500,"description":"Part number (one per sheet: 409 duplicate otherwise). Required on create; cannot be cleared."},"description":{"type":["string","null"],"maxLength":500,"description":"Description."},"list_price":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":9999999999,"description":"List price. A number (or decimal text) at or above 0, at most 4 decimal places, or null (\"$1,200\" is refused)."},"upc":{"type":["string","null"],"maxLength":500,"description":"UPC code."},"uom":{"type":["string","null"],"maxLength":500,"description":"Unit of measure."},"weight":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":9999999999,"description":"Weight. A number (or decimal text) at or above 0, at most 4 decimal places, or null."},"price_code":{"type":["string","null"],"maxLength":500,"description":"Price code (a numeric code is stored without leading zeros: \"010\" is \"10\")."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."},"other":{"type":["string","null"],"maxLength":500,"description":"Other."}},"required":["price_sheet_id","part_number"]},"PriceSheetRowPatch":{"type":"object","additionalProperties":false,"properties":{"price_sheet_id":{"type":"string","format":"uuid","description":"The price sheet the row is on. A price sheet of this workspace (404 Linked record not found otherwise)."},"manufacturer":{"type":["string","null"],"maxLength":500,"description":"The manufacturer as the imported file named it (descriptive only: the sheet is authoritative)."},"part_number":{"type":"string","maxLength":500,"description":"Part number (one per sheet: 409 duplicate otherwise). Required on create; cannot be cleared."},"description":{"type":["string","null"],"maxLength":500,"description":"Description."},"list_price":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":9999999999,"description":"List price. A number (or decimal text) at or above 0, at most 4 decimal places, or null (\"$1,200\" is refused)."},"upc":{"type":["string","null"],"maxLength":500,"description":"UPC code."},"uom":{"type":["string","null"],"maxLength":500,"description":"Unit of measure."},"weight":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":9999999999,"description":"Weight. A number (or decimal text) at or above 0, at most 4 decimal places, or null."},"price_code":{"type":["string","null"],"maxLength":500,"description":"Price code (a numeric code is stored without leading zeros: \"010\" is \"10\")."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."},"other":{"type":["string","null"],"maxLength":500,"description":"Other."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"SPACreate":{"type":"object","additionalProperties":false,"properties":{"spa_number":{"type":["string","null"],"maxLength":500,"description":"SPA number (one per workspace: 409 duplicate otherwise)."},"distributor_account_id":{"type":["string","null"],"format":"uuid","description":"The distributor company. A company of this workspace that GET /api/v1/accounts/{id} shows the token's owner (404 Linked record not found otherwise); checked when set or changed."},"distributor":{"type":["string","null"],"maxLength":500,"description":"The distributor's name as entered."},"customer_account_id":{"type":["string","null"],"format":"uuid","description":"The customer company. A company of this workspace that GET /api/v1/accounts/{id} shows the token's owner (404 Linked record not found otherwise); checked when set or changed."},"customer":{"type":["string","null"],"maxLength":500,"description":"The customer's name as entered."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer. A live manufacturer of this workspace inside the owner's manufacturers read scope (404 Linked record not found otherwise); checked when set or changed."},"manufacturer":{"type":["string","null"],"maxLength":500,"description":"The manufacturer's name as entered."},"price_code":{"type":["string","null"],"maxLength":500,"description":"Price code (a numeric code is stored without leading zeros: \"010\" is \"10\")."},"series_group":{"type":["string","null"],"maxLength":500,"description":"Series group."},"acc":{"type":["string","null"],"maxLength":500,"description":"ACC."},"multiplier":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,6})?$","minimum":0,"maximum":999999,"description":"The agreement's multiplier. A number (or decimal text) above 0, at most 6 decimal places, or null (0 is refused)."},"effective_date":{"type":["string","null"],"maxLength":40,"description":"Effective. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"expiration_date":{"type":["string","null"],"maxLength":40,"description":"Expires. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."}}},"SPAPatch":{"type":"object","additionalProperties":false,"properties":{"spa_number":{"type":["string","null"],"maxLength":500,"description":"SPA number (one per workspace: 409 duplicate otherwise)."},"distributor_account_id":{"type":["string","null"],"format":"uuid","description":"The distributor company. A company of this workspace that GET /api/v1/accounts/{id} shows the token's owner (404 Linked record not found otherwise); checked when set or changed."},"distributor":{"type":["string","null"],"maxLength":500,"description":"The distributor's name as entered."},"customer_account_id":{"type":["string","null"],"format":"uuid","description":"The customer company. A company of this workspace that GET /api/v1/accounts/{id} shows the token's owner (404 Linked record not found otherwise); checked when set or changed."},"customer":{"type":["string","null"],"maxLength":500,"description":"The customer's name as entered."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer. A live manufacturer of this workspace inside the owner's manufacturers read scope (404 Linked record not found otherwise); checked when set or changed."},"manufacturer":{"type":["string","null"],"maxLength":500,"description":"The manufacturer's name as entered."},"price_code":{"type":["string","null"],"maxLength":500,"description":"Price code (a numeric code is stored without leading zeros: \"010\" is \"10\")."},"series_group":{"type":["string","null"],"maxLength":500,"description":"Series group."},"acc":{"type":["string","null"],"maxLength":500,"description":"ACC."},"multiplier":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,6})?$","minimum":0,"maximum":999999,"description":"The agreement's multiplier. A number (or decimal text) above 0, at most 6 decimal places, or null (0 is refused)."},"effective_date":{"type":["string","null"],"maxLength":40,"description":"Effective. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"expiration_date":{"type":["string","null"],"maxLength":40,"description":"Expires. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"ManufacturerRatePatch":{"type":"object","additionalProperties":false,"properties":{"commission_rate":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,6})?$","minimum":0,"maximum":1,"description":"The default commission rate as a fraction (0.08 = 8%). A number (or decimal text) from 0 to 1, at most 6 decimal places (\"8%\" is refused), or null."},"commission_rate_notes":{"type":["string","null"],"maxLength":4000,"description":"Notes on the rate."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"TariffSurchargeCreate":{"type":"object","additionalProperties":false,"properties":{"manufacturer":{"type":"string","maxLength":500,"description":"The manufacturer, by name. Required on create; cannot be cleared."},"product_line":{"type":["string","null"],"maxLength":500,"description":"Product line (blank: every line)."},"price_code":{"type":["string","null"],"maxLength":500,"description":"Price code (a numeric code is stored without leading zeros: \"010\" is \"10\")."},"surcharge_pct":{"type":["number","string"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":1000,"description":"The surcharge in percent. A number (or decimal text) from 0 to 1000, at most 4 decimal places (25 = 25%; \"25%\" is refused). Required on create."},"includes_duty":{"type":"boolean","description":"The surcharge already passes the duty through (no duty estimate on top). true or false (default false)."},"effective_date":{"type":["string","null"],"maxLength":40,"description":"Effective. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"expiration_date":{"type":["string","null"],"maxLength":40,"description":"Expires. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."}},"required":["manufacturer","surcharge_pct"]},"TariffSurchargePatch":{"type":"object","additionalProperties":false,"properties":{"manufacturer":{"type":"string","maxLength":500,"description":"The manufacturer, by name. Required on create; cannot be cleared."},"product_line":{"type":["string","null"],"maxLength":500,"description":"Product line (blank: every line)."},"price_code":{"type":["string","null"],"maxLength":500,"description":"Price code (a numeric code is stored without leading zeros: \"010\" is \"10\")."},"surcharge_pct":{"type":["number","string"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":1000,"description":"The surcharge in percent. A number (or decimal text) from 0 to 1000, at most 4 decimal places (25 = 25%; \"25%\" is refused). Required on create."},"includes_duty":{"type":"boolean","description":"The surcharge already passes the duty through (no duty estimate on top). true or false (default false)."},"effective_date":{"type":["string","null"],"maxLength":40,"description":"Effective. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"expiration_date":{"type":["string","null"],"maxLength":40,"description":"Expires. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"OriginDefaultCreate":{"type":"object","additionalProperties":false,"properties":{"manufacturer":{"type":"string","maxLength":500,"description":"The manufacturer, by name. Required on create; cannot be cleared."},"product_line":{"type":["string","null"],"maxLength":500,"description":"Product line (blank: every line)."},"hts_code":{"type":["string","null"],"maxLength":500,"description":"HTS code. 4, 6, 8 or 10 digits (dots allowed), or null."},"country_of_origin":{"type":["string","null"],"maxLength":500,"description":"Country of origin. A 2-letter code or an English country name, or null."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."}},"required":["manufacturer"]},"OriginDefaultPatch":{"type":"object","additionalProperties":false,"properties":{"manufacturer":{"type":"string","maxLength":500,"description":"The manufacturer, by name. Required on create; cannot be cleared."},"product_line":{"type":["string","null"],"maxLength":500,"description":"Product line (blank: every line)."},"hts_code":{"type":["string","null"],"maxLength":500,"description":"HTS code. 4, 6, 8 or 10 digits (dots allowed), or null."},"country_of_origin":{"type":["string","null"],"maxLength":500,"description":"Country of origin. A 2-letter code or an English country name, or null."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"DutyRuleCreate":{"type":"object","additionalProperties":false,"properties":{"program":{"type":"string","maxLength":500,"description":"The duty program (e.g. Section 301). Required on create; cannot be cleared."},"hts_prefix":{"type":["string","null"],"maxLength":500,"description":"HTS prefix. 2, 4, 6, 8 or 10 digits (dots allowed), or null."},"country_of_origin":{"type":["string","null"],"maxLength":500,"description":"Country of origin. A 2-letter code or an English country name, or null."},"duty_pct":{"type":["number","string"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":1000,"description":"The duty in percent. A number (or decimal text) from 0 to 1000, at most 4 decimal places (25 = 25%; \"25%\" is refused). Required on create."},"applies_as":{"type":"string","enum":["add","replace"],"description":"add: on top of the HTS base rate; replace: instead of it. add or replace (default add)."},"effective_date":{"type":["string","null"],"maxLength":40,"description":"Effective. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"expiration_date":{"type":["string","null"],"maxLength":40,"description":"Expires. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."}},"required":["program","duty_pct"]},"DutyRulePatch":{"type":"object","additionalProperties":false,"properties":{"program":{"type":"string","maxLength":500,"description":"The duty program (e.g. Section 301). Required on create; cannot be cleared."},"hts_prefix":{"type":["string","null"],"maxLength":500,"description":"HTS prefix. 2, 4, 6, 8 or 10 digits (dots allowed), or null."},"country_of_origin":{"type":["string","null"],"maxLength":500,"description":"Country of origin. A 2-letter code or an English country name, or null."},"duty_pct":{"type":["number","string"],"pattern":"^-?\\d+(\\.\\d{1,4})?$","minimum":0,"maximum":1000,"description":"The duty in percent. A number (or decimal text) from 0 to 1000, at most 4 decimal places (25 = 25%; \"25%\" is refused). Required on create."},"applies_as":{"type":"string","enum":["add","replace"],"description":"add: on top of the HTS base rate; replace: instead of it. add or replace (default add)."},"effective_date":{"type":["string","null"],"maxLength":40,"description":"Effective. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"expiration_date":{"type":["string","null"],"maxLength":40,"description":"Expires. An ISO 8601 date (YYYY-MM-DD); Expires must be on or after Effective (422)."},"notes":{"type":["string","null"],"maxLength":4000,"description":"Notes."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the record has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it."}}},"DeletionListResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The deleted record's id."},"resource":{"type":"string","enum":["accounts","contacts","quotes","activities","manufacturers","products","leads","sales","commissions","inventory","samples","line-sheets","opportunities","account-contacts"],"description":"The resource the request named."},"deletedAt":{"type":"string","format":"date-time","description":"When it was deleted (a soft delete's stamp; a hard delete's journal time)."},"kind":{"type":"string","enum":["soft","hard"],"description":"soft: stamped and restorable for 30 days; hard: purged or hard-deleted."},"accountId":{"type":"string","format":"uuid","description":"account-contacts rows only: the removed link's company (id is the link's own id)."},"contactId":{"type":"string","format":"uuid","description":"account-contacts rows only: the removed link's contact."}},"required":["id","resource","deletedAt","kind"]}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"type":"object","properties":{"fields":{"type":"array","items":{"type":"string"}},"includes":{"type":"array","items":{"type":"string"},"description":"The includes embedded on this page (the include parameter's names, in order); empty when none was sent or the list takes none."},"updatedSince":{"type":["string","null"],"format":"date-time"},"createdSince":{"type":["string","null"],"format":"date-time"},"nextCursor":{"type":["string","null"]},"journalRetainedFrom":{"type":"string","format":"date-time","description":"The oldest deletedAt a hard row is still kept for: now minus 12 months. Hard rows deleted before it may already be pruned (a daily job)."},"sinceBeforeJournalWindow":{"type":"boolean","description":"true when since is earlier than journalRetainedFrom: hard rows deleted between the two may be missing, so run the reconcile. false when since is absent or within the window."}},"required":["journalRetainedFrom","sinceBeforeJournalWindow"]}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"QuoteItemListResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"object","properties":{"quote_id":{"type":"string","format":"uuid","description":"The quote's id."},"total":{"type":["number","null"],"description":"The quote's stored total (the app's Total). Left out when the token owner's role has the quote Total hidden."},"updated_at":{"type":["string","null"],"description":"When the quote last changed.","format":"date-time"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The line's id. Every save from the app writes the lines again, so ids change."},"line_no":{"type":"integer","description":"The line's position (1, 2, ...)."},"quantity":{"type":"number","description":"Quantity."},"pricing_uom":{"type":["string","null"],"description":"Pricing unit of measure."},"part_number":{"type":["string","null"],"description":"Part number."},"description":{"type":["string","null"],"description":"Description, as stored."},"weight":{"type":["number","null"],"description":"Weight."},"unit_price":{"type":["number","null"],"description":"Unit (net) price in the workspace currency. Left out when the token owner's role has the quote Total hidden."},"lead_time":{"type":["string","null"],"description":"Lead time, as text."},"total_amount":{"type":["number","null"],"description":"Extended price in the workspace currency. Left out when the token owner's role has the quote Total hidden."},"note":{"type":["string","null"],"description":"The line's note, as stored."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"product_id":{"type":["string","null"],"description":"The catalog product (GET /api/v1/products/{id}). Multiplier pricing only.","format":"uuid"},"manufacturer":{"type":["string","null"],"description":"The line's manufacturer name. Multiplier pricing only."},"list_price":{"type":["number","null"],"description":"The list price snapshot. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers. Left out when the token owner's role has the quote Total hidden. Also left out, with the other list pricing keys, when the role has the product List Price or Multiplier hidden."},"multiplier":{"type":["number","null"],"description":"The multiplier snapshot. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers. Left out when the token owner's role has the quote Total hidden. Also left out, with the other list pricing keys, when the role has the product List Price or Multiplier hidden."},"target_margin":{"type":["number","null"],"description":"The Dist. margin (0 to 1). Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers. Left out when the token owner's role has the quote Total hidden."},"multiplier_source":{"type":["string","null"],"description":"Where the multiplier came from. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers."},"price_code":{"type":["string","null"],"description":"The price code the multiplier was picked by. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers."},"tier":{"type":["string","null"],"description":"The tier the multiplier was picked by. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers."},"region":{"type":["string","null"],"description":"The region the multiplier was picked by. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers."},"list_currency":{"type":["string","null"],"description":"A foreign price sheet's currency. Multi-currency only."},"list_price_original":{"type":["number","null"],"description":"The list price in list_currency. Multi-currency only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers. Left out when the token owner's role has the quote Total hidden. Also left out, with the other list pricing keys, when the role has the product List Price or Multiplier hidden."},"list_fx_rate":{"type":["number","null"],"description":"The rate list_price was converted at. Multi-currency only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers. Left out when the token owner's role has the quote Total hidden. Also left out, with the other list pricing keys, when the role has the product List Price or Multiplier hidden."},"tariff_surcharge_pct":{"type":["number","null"],"description":"Tariff surcharge percent (25 = 25%). Tariffs only."},"tariff_duty_pct":{"type":["number","null"],"description":"Tariff duty percent. Tariffs only."},"tariff_detail":{"type":["object","null"],"description":"Tariff detail. Tariffs only. Left out when the token owner's role has the quote Total hidden."},"section":{"type":["string","null"],"description":"The section heading the line sits under. Quote sections only."},"is_optional":{"type":["boolean","null"],"description":"An optional line, outside the total. Quote sections only."}},"required":["id"]}}},"required":["quote_id","updated_at","items"]}},"required":["ok","data","requestId","apiVersion","deprecated"]},"InventoryMovementListResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"inventory_id":{"type":"string","format":"uuid"},"action_type":{"type":"string","description":"receive, remove, transfer_bin, assign_owner, a transfer or a count."},"quantity":{"type":["integer","null"]},"stock_before":{"type":["integer","null"]},"stock_after":{"type":["integer","null"]},"bin_from":{"type":["string","null"]},"bin_to":{"type":["string","null"]},"assigned_from":{"type":["string","null"]},"assigned_to":{"type":["string","null"]},"note":{"type":["string","null"]},"location_id":{"type":["string","null"],"format":"uuid"},"to_location_id":{"type":["string","null"],"format":"uuid"},"origin":{"type":["string","null"]},"actor_user_id":{"type":["string","null"],"format":"uuid"},"actor_name":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}},"required":["id"]}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"InventoryLocationListResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"parent_location_id":{"type":["string","null"],"format":"uuid"},"location_type":{"type":["string","null"]},"code":{"type":"string"},"name":{"type":["string","null"]},"description":{"type":["string","null"]},"active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id"]}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"InventoryBalanceListResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"object","properties":{"inventory_id":{"type":"string","format":"uuid"},"houston_stock":{"type":["integer","null"]},"balances":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"inventory_id":{"type":"string","format":"uuid"},"location_id":{"type":"string","format":"uuid"},"on_hand":{"type":["integer","null"]},"reserved":{"type":["integer","null"]},"inbound":{"type":["integer","null"]},"damaged":{"type":["integer","null"]},"unavailable":{"type":["integer","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id"]}}},"required":["inventory_id","houston_stock","balances"]}},"required":["ok","data","requestId","apiVersion","deprecated"]},"InventoryMovementResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"object","properties":{"item":{"type":"object","description":"The inventory item as GET /api/v1/inventory/{id} returns it after the movement."},"movement":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"inventory_id":{"type":"string","format":"uuid"},"action_type":{"type":"string","description":"receive, remove, transfer_bin, assign_owner, a transfer or a count."},"quantity":{"type":["integer","null"]},"stock_before":{"type":["integer","null"]},"stock_after":{"type":["integer","null"]},"bin_from":{"type":["string","null"]},"bin_to":{"type":["string","null"]},"assigned_from":{"type":["string","null"]},"assigned_to":{"type":["string","null"]},"note":{"type":["string","null"]},"location_id":{"type":["string","null"],"format":"uuid"},"to_location_id":{"type":["string","null"],"format":"uuid"},"origin":{"type":["string","null"]},"actor_user_id":{"type":["string","null"],"format":"uuid"},"actor_name":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}},"required":["id"]}},"required":["item","movement"]},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"InventoryMoveResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The inventory item."},"movement_id":{"type":["string","null"],"format":"uuid"},"from_location_id":{"type":"string","format":"uuid"},"to_location_id":{"type":"string","format":"uuid"},"quantity":{"type":"integer"},"from_on_hand":{"type":["integer","null"],"description":"The source's on-hand after the move."},"houston_stock":{"type":["integer","null"],"description":"The item's stock after the move; null when the ledger function does not report it."}},"required":["id","from_location_id","to_location_id","quantity"]},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"InventoryBalanceResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The inventory item."},"balance":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"inventory_id":{"type":"string","format":"uuid"},"location_id":{"type":"string","format":"uuid"},"on_hand":{"type":["integer","null"]},"reserved":{"type":["integer","null"]},"inbound":{"type":["integer","null"]},"damaged":{"type":["integer","null"]},"unavailable":{"type":["integer","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id"]},"houston_stock":{"type":["integer","null"],"description":"A linked item only: its stock after the write."}},"required":["id","balance"]},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"InventoryLocationResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"parent_location_id":{"type":["string","null"],"format":"uuid"},"location_type":{"type":["string","null"]},"code":{"type":"string"},"name":{"type":["string","null"]},"description":{"type":["string","null"]},"active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id"]},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"QuoteWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"object","description":"The quote as GET /api/v1/quotes/{id} returns it.","additionalProperties":true},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"QuoteCreate":{"type":"object","additionalProperties":false,"properties":{"quote_number":{"type":["string","null"],"maxLength":100,"description":"Create only. Left out or null: numbered automatically as the app does. A taken number is a 409 duplicate."},"lost_reason":{"type":["string","null"],"maxLength":200,"description":"Why the quote was lost. Kept only on a Lost quote (the app's lost rules): a move out of Lost clears it, and a non-blank value on a quote that does not end the request Lost is a 422 (close_fields_need_lost). Read back with lost_competitor and closed_at (server-stamped, read only)."},"lost_competitor":{"type":["string","null"],"maxLength":200,"description":"The competitor it was lost to. Kept only on a Lost quote, as lost_reason."},"stage":{"type":["string","null"],"maxLength":100,"description":"The stage (a workspace stage name). The order draft stage is refused (422); a Won stage is refused on create (422) and on a move (403) until sales can be written."},"quote_date":{"type":["string","null"],"maxLength":40,"description":"The quote's date (YYYY-MM-DD). Left out on create: the workspace's day."},"exp_date":{"type":["string","null"],"maxLength":40,"description":"When the quote expires (YYYY-MM-DD). Left out on create: the quote date plus the workspace's quote validity."},"follow_up_date":{"type":["string","null"],"maxLength":40,"description":"The follow-up date (YYYY-MM-DD)."},"account_id":{"type":["string","null"],"format":"uuid","description":"The company. Must be one the token owner can read (else 404 Linked record not found)."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The contact. Must be one the token owner can read (else 404 Linked record not found)."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer. Must be one the token owner can read (else 404 Linked record not found)."},"customer_account_id":{"type":["string","null"],"format":"uuid","description":"The end customer's company. Must be one the token owner can read."},"distributor_contact_id":{"type":["string","null"],"format":"uuid","description":"The distributor contact. Must be one the token owner can read."},"account_manager":{"type":["string","null"],"maxLength":200,"description":"The account manager's name."},"project":{"type":["string","null"],"maxLength":300,"description":"The project."},"end_user":{"type":["string","null"],"maxLength":300,"description":"The end user."},"po_number":{"type":["string","null"],"maxLength":100,"description":"The customer's PO number."},"prepared_by":{"type":["string","null"],"maxLength":200,"description":"The quote's Owner. A member's key creates a quote owned by nobody or by its owner and never changes it (403)."},"macro_summary":{"type":["string","null"],"maxLength":10000,"description":"The summary."},"notes":{"type":["string","null"],"maxLength":10000,"description":"Notes."},"win_probability":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":0,"maximum":100,"description":"0 to 100, at most 2 decimals."},"spa_amount":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":-999999999999.99,"maximum":999999999999.99,"description":"At most 2 decimals."},"total":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":-999999999999.99,"maximum":999999999999.99,"description":"At most 2 decimals. A quote with line items takes its total from them (409 total_follows_lines)."}}},"QuotePatch":{"type":"object","additionalProperties":false,"properties":{"lost_reason":{"type":["string","null"],"maxLength":200,"description":"Why the quote was lost. Kept only on a Lost quote (the app's lost rules): a move out of Lost clears it, and a non-blank value on a quote that does not end the request Lost is a 422 (close_fields_need_lost). Read back with lost_competitor and closed_at (server-stamped, read only)."},"lost_competitor":{"type":["string","null"],"maxLength":200,"description":"The competitor it was lost to. Kept only on a Lost quote, as lost_reason."},"stage":{"type":["string","null"],"maxLength":100,"description":"The stage (a workspace stage name). The order draft stage is refused (422); a Won stage is refused on create (422) and on a move (403) until sales can be written."},"quote_date":{"type":["string","null"],"maxLength":40,"description":"The quote's date (YYYY-MM-DD). Left out on create: the workspace's day."},"exp_date":{"type":["string","null"],"maxLength":40,"description":"When the quote expires (YYYY-MM-DD). Left out on create: the quote date plus the workspace's quote validity."},"follow_up_date":{"type":["string","null"],"maxLength":40,"description":"The follow-up date (YYYY-MM-DD)."},"account_id":{"type":["string","null"],"format":"uuid","description":"The company. Must be one the token owner can read (else 404 Linked record not found)."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The contact. Must be one the token owner can read (else 404 Linked record not found)."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer. Must be one the token owner can read (else 404 Linked record not found)."},"customer_account_id":{"type":["string","null"],"format":"uuid","description":"The end customer's company. Must be one the token owner can read."},"distributor_contact_id":{"type":["string","null"],"format":"uuid","description":"The distributor contact. Must be one the token owner can read."},"account_manager":{"type":["string","null"],"maxLength":200,"description":"The account manager's name."},"project":{"type":["string","null"],"maxLength":300,"description":"The project."},"end_user":{"type":["string","null"],"maxLength":300,"description":"The end user."},"po_number":{"type":["string","null"],"maxLength":100,"description":"The customer's PO number."},"prepared_by":{"type":["string","null"],"maxLength":200,"description":"The quote's Owner. A member's key creates a quote owned by nobody or by its owner and never changes it (403)."},"macro_summary":{"type":["string","null"],"maxLength":10000,"description":"The summary."},"notes":{"type":["string","null"],"maxLength":10000,"description":"Notes."},"win_probability":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":0,"maximum":100,"description":"0 to 100, at most 2 decimals."},"spa_amount":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":-999999999999.99,"maximum":999999999999.99,"description":"At most 2 decimals."},"total":{"type":["number","string","null"],"pattern":"^-?\\d+(\\.\\d{1,2})?$","minimum":-999999999999.99,"maximum":999999999999.99,"description":"At most 2 decimals. A quote with line items takes its total from them (409 total_follows_lines)."},"expected_updated_at":{"$ref":"#/components/schemas/ExpectedUpdatedAt","description":"The updated_at you last read: if the quote has changed since, the write is a 409 (latestUpdatedAt) instead of overwriting it. The If-Match header says the same."}}},"AccountContactLinkListResponse":{"type":"object","properties":{"ok":{"type":"boolean","example":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The link's own id."},"account_id":{"type":"string","format":"uuid","description":"The company (GET /api/v1/accounts/{id})."},"contact_id":{"type":"string","format":"uuid","description":"The contact (GET /api/v1/contacts/{id})."},"created_at":{"type":"string","format":"date-time","description":"When the link was made."}},"required":["id"]}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"EmbeddedAccountContactLinks":{"type":"object","description":"Company-contact links (ids only), as GET /api/v1/accounts/{id}/contacts and GET /api/v1/contacts/{id}/accounts list them, embedded by include: the first 100 rows the token may read, in the child endpoint's order. has_more: the record has more rows than embedded; page them with GET /api/v1/accounts/{id}/contacts (or /api/v1/contacts/{id}/accounts).","properties":{"data":{"type":"array","maxItems":100,"items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The link's own id."},"account_id":{"type":"string","format":"uuid","description":"The company (GET /api/v1/accounts/{id})."},"contact_id":{"type":"string","format":"uuid","description":"The contact (GET /api/v1/contacts/{id})."},"created_at":{"type":"string","format":"date-time","description":"When the link was made."}},"required":["id"]}},"has_more":{"type":"boolean","description":"true when the record has more than 100 rows; read the rest from GET /api/v1/accounts/{id}/contacts (or /api/v1/contacts/{id}/accounts)."}},"required":["data","has_more"]},"EmbeddedQuoteItems":{"type":"object","description":"Quote line items, as GET /api/v1/quotes/{id}/items lists them, embedded by include: the first 100 rows the token may read, in the child endpoint's order. has_more: the record has more rows than embedded; page them with GET /api/v1/quotes/{id}/items.","properties":{"data":{"type":"array","maxItems":100,"items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The line's id. Every save from the app writes the lines again, so ids change."},"line_no":{"type":"integer","description":"The line's position (1, 2, ...)."},"quantity":{"type":"number","description":"Quantity."},"pricing_uom":{"type":["string","null"],"description":"Pricing unit of measure."},"part_number":{"type":["string","null"],"description":"Part number."},"description":{"type":["string","null"],"description":"Description, as stored."},"weight":{"type":["number","null"],"description":"Weight."},"unit_price":{"type":["number","null"],"description":"Unit (net) price in the workspace currency. Left out when the token owner's role has the quote Total hidden."},"lead_time":{"type":["string","null"],"description":"Lead time, as text."},"total_amount":{"type":["number","null"],"description":"Extended price in the workspace currency. Left out when the token owner's role has the quote Total hidden."},"note":{"type":["string","null"],"description":"The line's note, as stored."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"product_id":{"type":["string","null"],"description":"The catalog product (GET /api/v1/products/{id}). Multiplier pricing only.","format":"uuid"},"manufacturer":{"type":["string","null"],"description":"The line's manufacturer name. Multiplier pricing only."},"list_price":{"type":["number","null"],"description":"The list price snapshot. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers. Left out when the token owner's role has the quote Total hidden. Also left out, with the other list pricing keys, when the role has the product List Price or Multiplier hidden."},"multiplier":{"type":["number","null"],"description":"The multiplier snapshot. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers. Left out when the token owner's role has the quote Total hidden. Also left out, with the other list pricing keys, when the role has the product List Price or Multiplier hidden."},"target_margin":{"type":["number","null"],"description":"The Dist. margin (0 to 1). Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers. Left out when the token owner's role has the quote Total hidden."},"multiplier_source":{"type":["string","null"],"description":"Where the multiplier came from. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers."},"price_code":{"type":["string","null"],"description":"The price code the multiplier was picked by. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers."},"tier":{"type":["string","null"],"description":"The tier the multiplier was picked by. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers."},"region":{"type":["string","null"],"description":"The region the multiplier was picked by. Multiplier pricing only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers."},"list_currency":{"type":["string","null"],"description":"A foreign price sheet's currency. Multi-currency only."},"list_price_original":{"type":["number","null"],"description":"The list price in list_currency. Multi-currency only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers. Left out when the token owner's role has the quote Total hidden. Also left out, with the other list pricing keys, when the role has the product List Price or Multiplier hidden."},"list_fx_rate":{"type":["number","null"],"description":"The rate list_price was converted at. Multi-currency only; null unless the token owner (and, for a token an admin created for its owner, that admin) may view multipliers. Left out when the token owner's role has the quote Total hidden. Also left out, with the other list pricing keys, when the role has the product List Price or Multiplier hidden."},"tariff_surcharge_pct":{"type":["number","null"],"description":"Tariff surcharge percent (25 = 25%). Tariffs only."},"tariff_duty_pct":{"type":["number","null"],"description":"Tariff duty percent. Tariffs only."},"tariff_detail":{"type":["object","null"],"description":"Tariff detail. Tariffs only. Left out when the token owner's role has the quote Total hidden."},"section":{"type":["string","null"],"description":"The section heading the line sits under. Quote sections only."},"is_optional":{"type":["boolean","null"],"description":"An optional line, outside the total. Quote sections only."}},"required":["id"]}},"has_more":{"type":"boolean","description":"true when the record has more than 100 rows; read the rest from GET /api/v1/quotes/{id}/items."}},"required":["data","has_more"]},"Account":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The company's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"account_name":{"type":["string","null"],"description":"The company's name (a rename follows onto its quotes, activities, contacts, sales and commissions)."},"account_status":{"type":["string","null"],"description":"Status, as text (Active, Prospect, Inactive, ...)."},"primary_phone":{"type":["string","null"],"description":"Main phone number."},"street_address":{"type":["string","null"],"description":"Street address."},"street_address_2":{"type":["string","null"],"description":"Street address, second line."},"city":{"type":["string","null"],"description":"City."},"state":{"type":["string","null"],"description":"State or region."},"zip_code":{"type":["string","null"],"description":"Postal code."},"territory":{"type":["string","null"],"description":"The company's territory, as the app types it (the territory code follows it unless territory_code is sent too)."},"territory_code":{"type":["string","null"],"description":"The territory's code."},"zone":{"type":["string","null"],"description":"Zone."},"mfg_int":{"type":["string","null"],"description":"Manufacturer interest, as text."},"account_manager":{"type":["string","null"],"description":"The company's account manager, as the app shows it (a name, email or user id: free text)."},"type":{"type":["string","null"],"description":"Company type."},"created_at":{"type":"string","format":"date-time","description":"When the company was created."},"updated_at":{"type":"string","format":"date-time","description":"When the company last changed: send it back as PATCH's expected_updated_at."},"parent_account_id":{"type":["string","null"],"format":"uuid","description":"The parent company (a branch's head office); null detaches it."},"is_master_account":{"type":"boolean","description":"Whether the company is a master account."},"ship_to_name":{"type":["string","null"],"description":"Ship-to name."},"ship_to_attention":{"type":["string","null"],"description":"Ship-to attention line."},"ship_to_street_address":{"type":["string","null"],"description":"Ship-to street address."},"ship_to_city":{"type":["string","null"],"description":"Ship-to city."},"ship_to_state":{"type":["string","null"],"description":"Ship-to state or region."},"ship_to_zip_code":{"type":["string","null"],"description":"Ship-to postal code."},"ship_to_country":{"type":["string","null"],"description":"Ship-to country."},"contacts":{"$ref":"#/components/schemas/EmbeddedAccountContactLinks","description":"Only with include=contacts. The company's contact links, as GET /api/v1/accounts/{id}/contacts lists them (ids only: the link's id, account_id, contact_id, created_at; oldest first). Needs the contacts:read scope too, and each link is listed only when the token owner could read that contact."}},"required":["id"]},"AccountListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The company's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"account_name":{"type":["string","null"],"description":"The company's name (a rename follows onto its quotes, activities, contacts, sales and commissions)."},"account_status":{"type":["string","null"],"description":"Status, as text (Active, Prospect, Inactive, ...)."},"primary_phone":{"type":["string","null"],"description":"Main phone number."},"city":{"type":["string","null"],"description":"City."},"state":{"type":["string","null"],"description":"State or region."},"zip_code":{"type":["string","null"],"description":"Postal code."},"territory":{"type":["string","null"],"description":"The company's territory, as the app types it (the territory code follows it unless territory_code is sent too)."},"territory_code":{"type":["string","null"],"description":"The territory's code."},"zone":{"type":["string","null"],"description":"Zone."},"account_manager":{"type":["string","null"],"description":"The company's account manager, as the app shows it (a name, email or user id: free text)."},"type":{"type":["string","null"],"description":"Company type."},"created_at":{"type":"string","format":"date-time","description":"When the company was created."},"updated_at":{"type":"string","format":"date-time","description":"When the company last changed: send it back as PATCH's expected_updated_at."},"contacts":{"$ref":"#/components/schemas/EmbeddedAccountContactLinks","description":"Only with include=contacts. The company's contact links, as GET /api/v1/accounts/{id}/contacts lists them (ids only: the link's id, account_id, contact_id, created_at; oldest first). Needs the contacts:read scope too, and each link is listed only when the token owner could read that contact."}},"required":["id"]},"AccountListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/AccountListItem"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"AccountResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Account"},"sync":{"type":"object","description":"Only when include was sent: the includes embedded on the record.","properties":{"includes":{"type":"array","items":{"type":"string"}}},"required":["includes"]}},"required":["ok","data","requestId","apiVersion","deprecated"]},"AccountSearchItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The company's id."},"account_name":{"type":["string","null"],"description":"The company's name (a rename follows onto its quotes, activities, contacts, sales and commissions)."},"territory":{"type":["string","null"],"description":"The company's territory, as the app types it (the territory code follows it unless territory_code is sent too)."},"territory_code":{"type":["string","null"],"description":"The territory's code."},"account_manager":{"type":["string","null"],"description":"The company's account manager, as the app shows it (a name, email or user id: free text)."},"updated_at":{"type":"string","format":"date-time","description":"When the company last changed: send it back as PATCH's expected_updated_at."}},"required":["id"]},"AccountSearchResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/AccountSearchItem"}}},"required":["ok","data","requestId","apiVersion","deprecated"]},"AccountWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Account"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."},"warning":{"type":"string","description":"Set when the company saved but its rename or copy onto linked records did not finish."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"Contact":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The contact's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"first_name":{"type":["string","null"],"description":"First name."},"last_name":{"type":["string","null"],"description":"Last name."},"company_name":{"type":["string","null"],"description":"Company name as text."},"phone":{"type":["string","null"],"description":"Phone number."},"title":{"type":["string","null"],"description":"Job title."},"full_name":{"type":["string","null"],"description":"Split into first_name / last_name when those are absent."},"email":{"type":["string","null"],"description":"Email address."},"account_id":{"type":["string","null"],"format":"uuid","description":"The contact's primary company."},"created_at":{"type":"string","format":"date-time","description":"When the contact was created."},"updated_at":{"type":"string","format":"date-time","description":"When the contact last changed."},"accounts":{"$ref":"#/components/schemas/EmbeddedAccountContactLinks","description":"Only with include=accounts. The contact's company links, as GET /api/v1/contacts/{id}/accounts lists them (ids only: the link's id, account_id, contact_id, created_at; oldest first). Needs the accounts:read scope too, and each link is listed only when the token owner could read that company."}},"required":["id"]},"ContactListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"ContactResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Contact"},"sync":{"type":"object","description":"Only when include was sent: the includes embedded on the record.","properties":{"includes":{"type":"array","items":{"type":"string"}}},"required":["includes"]}},"required":["ok","data","requestId","apiVersion","deprecated"]},"ContactSearchItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The contact's id."},"first_name":{"type":["string","null"],"description":"First name."},"last_name":{"type":["string","null"],"description":"Last name."},"company_name":{"type":["string","null"],"description":"Company name as text."},"phone":{"type":["string","null"],"description":"Phone number."},"title":{"type":["string","null"],"description":"Job title."},"full_name":{"type":["string","null"],"description":"Split into first_name / last_name when those are absent."},"email":{"type":["string","null"],"description":"Email address."},"account_id":{"type":["string","null"],"format":"uuid","description":"The contact's primary company."},"updated_at":{"type":"string","format":"date-time","description":"When the contact last changed."}},"required":["id"]},"ContactSearchResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/ContactSearchItem"}}},"required":["ok","data","requestId","apiVersion","deprecated"]},"ContactWriteResult":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The contact's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"first_name":{"type":["string","null"],"description":"First name."},"last_name":{"type":["string","null"],"description":"Last name."},"company_name":{"type":["string","null"],"description":"Company name as text."},"phone":{"type":["string","null"],"description":"Phone number."},"title":{"type":["string","null"],"description":"Job title."},"address":{"type":["string","null"],"description":"Street address."},"city":{"type":["string","null"],"description":"City."},"state":{"type":["string","null"],"description":"State or region."},"zip_code":{"type":["string","null"],"description":"Postal code."},"full_name":{"type":["string","null"],"description":"Split into first_name / last_name when those are absent."},"email":{"type":["string","null"],"description":"Email address."},"tags":{"type":"array","items":{"type":"string"},"description":"Up to 50 tags, deduplicated."},"account_id":{"type":["string","null"],"format":"uuid","description":"The contact's primary company."},"created_at":{"type":"string","format":"date-time","description":"When the contact was created."},"updated_at":{"type":"string","format":"date-time","description":"When the contact last changed."}},"required":["id"]},"ContactWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/ContactWriteResult"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."},"warning":{"type":"string","description":"Set when the contact saved but a follow-on step (an email or phone row) did not."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"ContactRestoreResult":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The contact's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"first_name":{"type":["string","null"],"description":"First name."},"last_name":{"type":["string","null"],"description":"Last name."},"company_name":{"type":["string","null"],"description":"Company name as text."},"phone":{"type":["string","null"],"description":"Phone number."},"title":{"type":["string","null"],"description":"Job title."},"full_name":{"type":["string","null"],"description":"Split into first_name / last_name when those are absent."},"email":{"type":["string","null"],"description":"Email address."},"account_id":{"type":["string","null"],"format":"uuid","description":"The contact's primary company."},"created_at":{"type":"string","format":"date-time","description":"When the contact was created."},"updated_at":{"type":"string","format":"date-time","description":"When the contact last changed."},"accounts":{"$ref":"#/components/schemas/EmbeddedAccountContactLinks","description":"Only with include=accounts. The contact's company links, as GET /api/v1/contacts/{id}/accounts lists them (ids only: the link's id, account_id, contact_id, created_at; oldest first). Needs the accounts:read scope too, and each link is listed only when the token owner could read that company."},"restore":{"type":"object","description":"What the restore brought back: counts only, never ids or labels. Absent on a replay whose first answer's counts could not be kept.","properties":{"restored":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"description":"Restored rows per table."},"relinked":{"type":"integer","minimum":0},"skipped":{"type":"integer","minimum":0}},"required":["restored","relinked","skipped"]}},"required":["id"]},"ContactRestoreResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/ContactRestoreResult"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"Activity":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The activity's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"type":{"type":"string","description":"Activity type, e.g. Call, Email, Meeting, Task, Note. Defaults to Task."},"subject":{"type":["string","null"],"description":"Subject line."},"activity_name":{"type":["string","null"],"description":"Activity name."},"description":{"type":["string","null"],"description":"Notes, as plain text (newlines kept)."},"account":{"type":["string","null"],"description":"Company name as text."},"contact":{"type":["string","null"],"description":"Contact name as text."},"manufacturer":{"type":["string","null"],"description":"Manufacturer name as text."},"end_user":{"type":["string","null"],"description":"End user name."},"end_user_contact":{"type":["string","null"],"description":"End user contact name."},"manufacturer_contact":{"type":["string","null"],"description":"Manufacturer contact name."},"assigned_to":{"type":["string","null"],"description":"A user id in the token's workspace."},"account_id":{"type":["string","null"],"format":"uuid","description":"The linked company."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The linked contact."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The linked manufacturer."},"quote_id":{"type":["string","null"],"format":"uuid","description":"The linked quote."},"sale_id":{"type":["string","null"],"format":"uuid","description":"The linked sale."},"activity_date":{"type":["string","null"],"format":"date","description":"ISO 8601 date or timestamp."},"due_date":{"type":["string","null"],"format":"date","description":"ISO 8601 date or timestamp."},"reminder_at":{"type":["string","null"],"format":"date-time","description":"ISO 8601 date or timestamp."},"completed":{"type":["boolean","null"],"description":"Whether the activity is done; empty (null) counts as not done in the app."},"priority":{"type":["string","null"],"description":"low, medium or high (any case); empty clears it, and an empty priority (null) counts as medium in the app."},"body":{"type":["string","null"],"description":"Synced mail body, as plain text."},"updated_at":{"type":"string","format":"date-time","description":"When the activity last changed."},"created_at":{"type":"string","format":"date-time","description":"When the activity was created."}},"required":["id"]},"ActivityListItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The activity's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"type":{"type":"string","description":"Activity type, e.g. Call, Email, Meeting, Task, Note. Defaults to Task."},"subject":{"type":["string","null"],"description":"Subject line."},"activity_name":{"type":["string","null"],"description":"Activity name."},"account":{"type":["string","null"],"description":"Company name as text."},"contact":{"type":["string","null"],"description":"Contact name as text."},"manufacturer":{"type":["string","null"],"description":"Manufacturer name as text."},"end_user":{"type":["string","null"],"description":"End user name."},"end_user_contact":{"type":["string","null"],"description":"End user contact name."},"manufacturer_contact":{"type":["string","null"],"description":"Manufacturer contact name."},"assigned_to":{"type":["string","null"],"description":"A user id in the token's workspace."},"account_id":{"type":["string","null"],"format":"uuid","description":"The linked company."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The linked contact."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The linked manufacturer."},"quote_id":{"type":["string","null"],"format":"uuid","description":"The linked quote."},"sale_id":{"type":["string","null"],"format":"uuid","description":"The linked sale."},"activity_date":{"type":["string","null"],"format":"date","description":"ISO 8601 date or timestamp."},"due_date":{"type":["string","null"],"format":"date","description":"ISO 8601 date or timestamp."},"reminder_at":{"type":["string","null"],"format":"date-time","description":"ISO 8601 date or timestamp."},"completed":{"type":["boolean","null"],"description":"Whether the activity is done; empty (null) counts as not done in the app."},"priority":{"type":["string","null"],"description":"low, medium or high (any case); empty clears it, and an empty priority (null) counts as medium in the app."},"updated_at":{"type":"string","format":"date-time","description":"When the activity last changed."},"created_at":{"type":"string","format":"date-time","description":"When the activity was created."}},"required":["id"]},"ActivityListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/ActivityListItem"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"ActivityResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Activity"}},"required":["ok","data","requestId","apiVersion","deprecated"]},"ActivityWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Activity"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."},"warning":{"type":"string","description":"Set when the activity saved but its recurrence or follow-up did not."},"nextActivityId":{"type":["string","null"],"format":"uuid","description":"Completing a recurring activity: the next occurrence's id."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"ActivityRestoreResult":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The activity's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"type":{"type":"string","description":"Activity type, e.g. Call, Email, Meeting, Task, Note. Defaults to Task."},"subject":{"type":["string","null"],"description":"Subject line."},"activity_name":{"type":["string","null"],"description":"Activity name."},"description":{"type":["string","null"],"description":"Notes, as plain text (newlines kept)."},"account":{"type":["string","null"],"description":"Company name as text."},"contact":{"type":["string","null"],"description":"Contact name as text."},"manufacturer":{"type":["string","null"],"description":"Manufacturer name as text."},"end_user":{"type":["string","null"],"description":"End user name."},"end_user_contact":{"type":["string","null"],"description":"End user contact name."},"manufacturer_contact":{"type":["string","null"],"description":"Manufacturer contact name."},"assigned_to":{"type":["string","null"],"description":"A user id in the token's workspace."},"account_id":{"type":["string","null"],"format":"uuid","description":"The linked company."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The linked contact."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The linked manufacturer."},"quote_id":{"type":["string","null"],"format":"uuid","description":"The linked quote."},"sale_id":{"type":["string","null"],"format":"uuid","description":"The linked sale."},"activity_date":{"type":["string","null"],"format":"date","description":"ISO 8601 date or timestamp."},"due_date":{"type":["string","null"],"format":"date","description":"ISO 8601 date or timestamp."},"reminder_at":{"type":["string","null"],"format":"date-time","description":"ISO 8601 date or timestamp."},"completed":{"type":["boolean","null"],"description":"Whether the activity is done; empty (null) counts as not done in the app."},"priority":{"type":["string","null"],"description":"low, medium or high (any case); empty clears it, and an empty priority (null) counts as medium in the app."},"body":{"type":["string","null"],"description":"Synced mail body, as plain text."},"updated_at":{"type":"string","format":"date-time","description":"When the activity last changed."},"created_at":{"type":"string","format":"date-time","description":"When the activity was created."},"restore":{"type":"object","description":"What the restore brought back: counts only, never ids or labels. Absent on a replay whose first answer's counts could not be kept.","properties":{"restored":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"description":"Restored rows per table."},"relinked":{"type":"integer","minimum":0},"skipped":{"type":"integer","minimum":0}},"required":["restored","relinked","skipped"]}},"required":["id"]},"ActivityRestoreResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/ActivityRestoreResult"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"Manufacturer":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The manufacturer's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"manufacturer_name":{"type":["string","null"],"description":"The manufacturer's name, unique in the workspace (a rename follows onto its quotes, sales, activities, commissions, products, inventory and the opportunities' principal lists)."},"parent_manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The parent manufacturer (set in the app)."},"terms_and_conditions":{"type":["string","null"],"description":"Terms and conditions, as plain text (newlines kept)."},"mfg_territory":{"type":["string","null"],"description":"The territory the manufacturer belongs to; it must stay inside the token owner's territories."},"expected_sales":{"type":["number","null"],"description":"Expected annual sales."},"primary_phone":{"type":["string","null"],"description":"Main phone number."},"city":{"type":["string","null"],"description":"City."},"state":{"type":["string","null"],"description":"State or region."},"zip_code":{"type":["string","null"],"description":"Postal code."},"regional_manager":{"type":["string","null"],"description":"The manufacturer's regional manager, as text."},"updated_at":{"type":"string","format":"date-time","description":"When the manufacturer last changed."}},"required":["id"]},"ManufacturerListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/Manufacturer"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"ManufacturerResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Manufacturer"}},"required":["ok","data","requestId","apiVersion","deprecated"]},"ManufacturerWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Manufacturer"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."},"warning":{"type":"string","description":"Set when a rename saved but could not be copied to every linked record."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"Product":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The product's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"stock":{"type":["boolean","null"],"description":"Whether the product is a stocked item."},"manufacturer_name":{"type":["string","null"],"description":"The manufacturer's name as text: with part_number, the product's catalog key in the workspace, and what a token owner limited to some manufacturers is matched by."},"part_number":{"type":["string","null"],"description":"Part number: with manufacturer_name, the product's catalog key in the workspace."},"product_family":{"type":["string","null"],"description":"Product family."},"product_line":{"type":["string","null"],"description":"Product line."},"root_part_no":{"type":["string","null"],"description":"Root part number."},"list_price":{"type":["number","null"],"description":"List price."},"stock_price":{"type":["number","null"],"description":"Stock price."},"commission_rate":{"type":["number","null"],"description":"Commission rate as a fraction (0.08 = 8%)."},"lead_time":{"type":["string","null"],"description":"Lead time as text."},"upc":{"type":["string","null"],"description":"UPC code."},"uom":{"type":["string","null"],"description":"Unit of measure."},"hou_stock":{"type":["integer","null"],"description":"Stock on hand in the first location stock column. Usually 0 or empty in a workspace that does not record stock here."},"pharr_stock":{"type":["integer","null"],"description":"Stock on hand in the second location stock column. Usually 0 or empty in a workspace that does not record stock here."},"reorder_level":{"type":["integer","null"],"description":"Reorder level."},"shipping_weight":{"type":["number","null"],"description":"Shipping weight."},"unit_cost":{"type":["number","null"],"description":"Unit cost. Returned only to a token whose owner is an admin or a manager (has reports)."},"description":{"type":["string","null"],"description":"Description."},"price_code":{"type":["string","null"],"description":"Price code."},"image_url":{"type":["string","null"],"description":"Image link (http or https)."},"specification_url":{"type":["string","null"],"description":"Specification sheet link (http or https)."},"notes":{"type":["string","null"],"description":"Notes."},"created_time":{"type":["string","null"],"description":"When the product was created, as a legacy import recorded it (text; read only)."},"modified_time":{"type":["string","null"],"description":"When the product was last modified, as a legacy import recorded it (text; read only)."},"created_at":{"type":"string","format":"date-time","description":"When the product was created."},"updated_at":{"type":"string","format":"date-time","description":"When the product last changed."}},"required":["id"]},"ProductListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/Product"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"ProductResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Product"}},"required":["ok","data","requestId","apiVersion","deprecated"]},"ProductWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Product"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"ProductRestoreResult":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The product's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"stock":{"type":["boolean","null"],"description":"Whether the product is a stocked item."},"manufacturer_name":{"type":["string","null"],"description":"The manufacturer's name as text: with part_number, the product's catalog key in the workspace, and what a token owner limited to some manufacturers is matched by."},"part_number":{"type":["string","null"],"description":"Part number: with manufacturer_name, the product's catalog key in the workspace."},"product_family":{"type":["string","null"],"description":"Product family."},"product_line":{"type":["string","null"],"description":"Product line."},"root_part_no":{"type":["string","null"],"description":"Root part number."},"list_price":{"type":["number","null"],"description":"List price."},"stock_price":{"type":["number","null"],"description":"Stock price."},"commission_rate":{"type":["number","null"],"description":"Commission rate as a fraction (0.08 = 8%)."},"lead_time":{"type":["string","null"],"description":"Lead time as text."},"upc":{"type":["string","null"],"description":"UPC code."},"uom":{"type":["string","null"],"description":"Unit of measure."},"hou_stock":{"type":["integer","null"],"description":"Stock on hand in the first location stock column. Usually 0 or empty in a workspace that does not record stock here."},"pharr_stock":{"type":["integer","null"],"description":"Stock on hand in the second location stock column. Usually 0 or empty in a workspace that does not record stock here."},"reorder_level":{"type":["integer","null"],"description":"Reorder level."},"shipping_weight":{"type":["number","null"],"description":"Shipping weight."},"unit_cost":{"type":["number","null"],"description":"Unit cost. Returned only to a token whose owner is an admin or a manager (has reports)."},"description":{"type":["string","null"],"description":"Description."},"price_code":{"type":["string","null"],"description":"Price code."},"image_url":{"type":["string","null"],"description":"Image link (http or https)."},"specification_url":{"type":["string","null"],"description":"Specification sheet link (http or https)."},"notes":{"type":["string","null"],"description":"Notes."},"created_time":{"type":["string","null"],"description":"When the product was created, as a legacy import recorded it (text; read only)."},"modified_time":{"type":["string","null"],"description":"When the product was last modified, as a legacy import recorded it (text; read only)."},"created_at":{"type":"string","format":"date-time","description":"When the product was created."},"updated_at":{"type":"string","format":"date-time","description":"When the product last changed."},"restore":{"type":"object","description":"What the restore brought back: counts only, never ids or labels. Absent on a replay whose first answer's counts could not be kept.","properties":{"restored":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"description":"Restored rows per table."},"relinked":{"type":"integer","minimum":0},"skipped":{"type":"integer","minimum":0}},"required":["restored","relinked","skipped"]}},"required":["id"]},"ProductRestoreResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/ProductRestoreResult"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"Lead":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The lead's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"company":{"type":"string","description":"The company the lead is for."},"contact_name":{"type":["string","null"],"description":"The person at the company."},"title":{"type":["string","null"],"description":"Their job title."},"email":{"type":["string","null"],"description":"Their email address."},"phone":{"type":["string","null"],"description":"Their phone number."},"source":{"type":["string","null"],"description":"Where the lead came from (Website, Trade Show, Referral, ...)."},"status":{"type":"string","description":"Where the lead stands. Defaults to New."},"priority":{"type":"string","description":"Hot, Warm or Cold. Defaults to Warm."},"assigned_to":{"type":["string","null"],"format":"uuid","description":"The user who owns the lead (a user id in the token's workspace). Empty unless set."},"territory":{"type":["string","null"],"description":"The lead's territory, as text (a territory code or name)."},"manufacturer_interest":{"type":["string","null"],"description":"The manufacturers the lead is interested in, as text (names separated by semicolons)."},"account_id":{"type":["string","null"],"format":"uuid","description":"The company record the lead is linked to."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The lead's primary contact record."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer record the lead is linked to."},"next_follow_up":{"type":["string","null"],"format":"date","description":"The next follow-up date (YYYY-MM-DD)."},"estimated_value":{"type":"number","description":"The lead's estimated value. Defaults to 0."},"notes":{"type":["string","null"],"description":"Notes, as plain text."},"last_touch_at":{"type":["string","null"],"format":"date-time","description":"When the lead was last touched (set by the server)."},"created_at":{"type":"string","format":"date-time","description":"When the lead was created."},"updated_at":{"type":"string","format":"date-time","description":"When the lead last changed."}},"required":["id"]},"LeadListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"LeadResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Lead"}},"required":["ok","data","requestId","apiVersion","deprecated"]},"LeadWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Lead"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"LeadRestoreResult":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The lead's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"company":{"type":"string","description":"The company the lead is for."},"contact_name":{"type":["string","null"],"description":"The person at the company."},"title":{"type":["string","null"],"description":"Their job title."},"email":{"type":["string","null"],"description":"Their email address."},"phone":{"type":["string","null"],"description":"Their phone number."},"source":{"type":["string","null"],"description":"Where the lead came from (Website, Trade Show, Referral, ...)."},"status":{"type":"string","description":"Where the lead stands. Defaults to New."},"priority":{"type":"string","description":"Hot, Warm or Cold. Defaults to Warm."},"assigned_to":{"type":["string","null"],"format":"uuid","description":"The user who owns the lead (a user id in the token's workspace). Empty unless set."},"territory":{"type":["string","null"],"description":"The lead's territory, as text (a territory code or name)."},"manufacturer_interest":{"type":["string","null"],"description":"The manufacturers the lead is interested in, as text (names separated by semicolons)."},"account_id":{"type":["string","null"],"format":"uuid","description":"The company record the lead is linked to."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The lead's primary contact record."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer record the lead is linked to."},"next_follow_up":{"type":["string","null"],"format":"date","description":"The next follow-up date (YYYY-MM-DD)."},"estimated_value":{"type":"number","description":"The lead's estimated value. Defaults to 0."},"notes":{"type":["string","null"],"description":"Notes, as plain text."},"last_touch_at":{"type":["string","null"],"format":"date-time","description":"When the lead was last touched (set by the server)."},"created_at":{"type":"string","format":"date-time","description":"When the lead was created."},"updated_at":{"type":"string","format":"date-time","description":"When the lead last changed."},"restore":{"type":"object","description":"What the restore brought back: counts only, never ids or labels. Absent on a replay whose first answer's counts could not be kept.","properties":{"restored":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"description":"Restored rows per table."},"relinked":{"type":"integer","minimum":0},"skipped":{"type":"integer","minimum":0}},"required":["restored","relinked","skipped"]}},"required":["id"]},"LeadRestoreResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/LeadRestoreResult"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"InventoryItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The item's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"item_name":{"type":["string","null"],"description":"Item name."},"manufacturer":{"type":["string","null"],"description":"Manufacturer name as text; must be in the key owner's manufacturer scope when they have one."},"part_number":{"type":["string","null"],"description":"Part number."},"description":{"type":["string","null"],"description":"Description."},"houston_stock":{"type":["integer","null"],"description":"Stock on hand, a whole number. Defaults to 0 on create. On an ERP-linked item a change is a count at the ERP's main location and needs expected_houston_stock."},"bin_location":{"type":["string","null"],"description":"Bin or shelf location."},"assigned_to":{"type":["string","null"],"description":"Who holds the item, as the name the app shows (the own-records lock reads it)."},"last_modified_by":{"type":["string","null"],"description":"Who last changed the item (set by the server)."},"created_at":{"type":"string","format":"date-time","description":"When the item was created."},"updated_at":{"type":"string","format":"date-time","description":"When the item last changed."}},"required":["id"]},"InventoryItemListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/InventoryItem"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"InventoryItemResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/InventoryItem"}},"required":["ok","data","requestId","apiVersion","deprecated"]},"InventoryItemWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/InventoryItem"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"InventoryItemRestoreResult":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The item's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"item_name":{"type":["string","null"],"description":"Item name."},"manufacturer":{"type":["string","null"],"description":"Manufacturer name as text; must be in the key owner's manufacturer scope when they have one."},"part_number":{"type":["string","null"],"description":"Part number."},"description":{"type":["string","null"],"description":"Description."},"houston_stock":{"type":["integer","null"],"description":"Stock on hand, a whole number. Defaults to 0 on create. On an ERP-linked item a change is a count at the ERP's main location and needs expected_houston_stock."},"bin_location":{"type":["string","null"],"description":"Bin or shelf location."},"assigned_to":{"type":["string","null"],"description":"Who holds the item, as the name the app shows (the own-records lock reads it)."},"last_modified_by":{"type":["string","null"],"description":"Who last changed the item (set by the server)."},"created_at":{"type":"string","format":"date-time","description":"When the item was created."},"updated_at":{"type":"string","format":"date-time","description":"When the item last changed."},"restore":{"type":"object","description":"What the restore brought back: counts only, never ids or labels. Absent on a replay whose first answer's counts could not be kept.","properties":{"restored":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"description":"Restored rows per table."},"relinked":{"type":"integer","minimum":0},"skipped":{"type":"integer","minimum":0}},"required":["restored","relinked","skipped"]}},"required":["id"]},"InventoryItemRestoreResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/InventoryItemRestoreResult"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"Sample":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The sample's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"manufacturer":{"type":["string","null"],"description":"Manufacturer name as text."},"part_number":{"type":["string","null"],"description":"Part number."},"description":{"type":["string","null"],"description":"Description."},"location":{"type":["string","null"],"description":"Where the sample is kept (a city or office)."},"houston_stock":{"type":["integer","null"],"description":"How many are on hand, a whole number. Defaults to 0 on create."},"bin_location":{"type":["string","null"],"description":"Bin or shelf location."},"assigned_to":{"type":["string","null"],"description":"Who has the sample checked out, as the name the app shows (free text). Setting it checks the sample out now; clearing it checks it back in."},"workflow_state":{"type":"string","description":"Where the sample is in its checkout workflow. lost, damaged, requested and approved are kept as sent; any other state is set from assigned_to (checked_out when someone has it, else available), as the app does."},"linked_account_id":{"type":["string","null"],"format":"uuid","description":"The company the sample is for: one the token's owner can read (else 404 Linked record not found; an owner without accounts read: 403, whatever the id). null unlinks."},"linked_contact_id":{"type":["string","null"],"format":"uuid","description":"The contact the sample is for: one the token's owner can read (else 404 Linked record not found; an owner without contacts read: 403, whatever the id). null unlinks."},"updated_at":{"type":"string","format":"date-time","description":"When the sample last changed."},"created_at":{"type":"string","format":"date-time","description":"When the sample was created."},"linked_account_name":{"type":["string","null"],"description":"The linked company's name; null with no linked company, or one the key's owner cannot read."},"linked_contact_name":{"type":["string","null"],"description":"The linked contact's name; null with no linked contact, or one the key's owner cannot read."}},"required":["id"]},"SampleListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/Sample"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"SampleResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Sample"}},"required":["ok","data","requestId","apiVersion","deprecated"]},"SampleWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Sample"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"SampleRestoreResult":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The sample's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"manufacturer":{"type":["string","null"],"description":"Manufacturer name as text."},"part_number":{"type":["string","null"],"description":"Part number."},"description":{"type":["string","null"],"description":"Description."},"location":{"type":["string","null"],"description":"Where the sample is kept (a city or office)."},"houston_stock":{"type":["integer","null"],"description":"How many are on hand, a whole number. Defaults to 0 on create."},"bin_location":{"type":["string","null"],"description":"Bin or shelf location."},"assigned_to":{"type":["string","null"],"description":"Who has the sample checked out, as the name the app shows (free text). Setting it checks the sample out now; clearing it checks it back in."},"workflow_state":{"type":"string","description":"Where the sample is in its checkout workflow. lost, damaged, requested and approved are kept as sent; any other state is set from assigned_to (checked_out when someone has it, else available), as the app does."},"linked_account_id":{"type":["string","null"],"format":"uuid","description":"The company the sample is for: one the token's owner can read (else 404 Linked record not found; an owner without accounts read: 403, whatever the id). null unlinks."},"linked_contact_id":{"type":["string","null"],"format":"uuid","description":"The contact the sample is for: one the token's owner can read (else 404 Linked record not found; an owner without contacts read: 403, whatever the id). null unlinks."},"updated_at":{"type":"string","format":"date-time","description":"When the sample last changed."},"created_at":{"type":"string","format":"date-time","description":"When the sample was created."},"linked_account_name":{"type":["string","null"],"description":"The linked company's name; null with no linked company, or one the key's owner cannot read."},"linked_contact_name":{"type":["string","null"],"description":"The linked contact's name; null with no linked contact, or one the key's owner cannot read."},"restore":{"type":"object","description":"What the restore brought back: counts only, never ids or labels. Absent on a replay whose first answer's counts could not be kept.","properties":{"restored":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"description":"Restored rows per table."},"relinked":{"type":"integer","minimum":0},"skipped":{"type":"integer","minimum":0}},"required":["restored","relinked","skipped"]}},"required":["id"]},"SampleRestoreResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/SampleRestoreResult"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"LineSheet":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The line sheet's id."},"workspace_id":{"type":"string","format":"uuid","description":"The token's workspace."},"title":{"type":"string","description":"The line sheet's title."},"reference_code":{"type":"string","description":"Stored in upper case; any run of characters other than A-Z, 0-9, ., _ and - becomes one -. Made from the title when a create leaves it out. On create a code another sheet in the workspace has gets the next free -2, -3, ... suffix; on update it is a 409."},"description":{"type":["string","null"],"description":"A description, as plain text."},"category":{"type":["string","null"],"description":"Category, e.g. Territory Line Sheet, Product Brochure, Stock Sheet."},"product_family":{"type":["string","null"],"description":"Product family."},"territory_codes":{"type":"array","items":{"type":"string"},"description":"Territory codes, stored in upper case; an entry holding commas, semicolons or line breaks is split."},"tags":{"type":"array","items":{"type":"string"},"description":"Tags; an entry holding commas, semicolons or line breaks is split."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The linked manufacturer: one in the token's workspace that is not deleted."},"source_kind":{"type":"string","description":"Where the file is: external_url (a web link), shared_path (a file-share path, returned as its file name only) or uploaded_file (uploaded in the app). Always external_url for a sheet the API creates or re-points."},"source_url":{"type":["string","null"],"description":"The web link. Another sheet in the workspace with the same link (ignoring case) is a 409. Sending it makes the sheet a web link; an uploaded sheet's file cannot be replaced through the API (422)."},"file_name":{"type":["string","null"],"description":"An uploaded sheet's file name."},"mime_type":{"type":["string","null"],"description":"An uploaded sheet's file type."},"file_size":{"type":["integer","null"],"description":"An uploaded sheet's size in bytes."},"active":{"type":"boolean","description":"false archives the sheet (archived_at is stamped); true brings it back. A new sheet is active unless the create says false."},"featured":{"type":"boolean","description":"Whether the sheet is featured. Defaults to false."},"created_by_name":{"type":["string","null"],"description":"Who created the sheet."},"created_at":{"type":"string","format":"date-time","description":"When the sheet was created."},"updated_at":{"type":"string","format":"date-time","description":"When the sheet last changed."},"archived_at":{"type":["string","null"],"format":"date-time","description":"When the sheet was archived (empty while active)."},"manufacturer_name":{"type":["string","null"],"description":"The linked manufacturer's name; null with no manufacturer, or one the key's owner cannot see."}},"required":["id"]},"LineSheetListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/LineSheet"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"LineSheetResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/LineSheet"}},"required":["ok","data","requestId","apiVersion","deprecated"]},"LineSheetWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/LineSheet"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"User":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The user's id (an assigned_to id names it)."},"user_name":{"type":["string","null"],"description":"The user's display name."},"email":{"type":["string","null"],"description":"The user's email address."},"status":{"type":"string","description":"The user's status as stored (Active, Inactive, ...); active says whether it lets them sign in."},"created_at":{"type":"string","format":"date-time","description":"When the user was added."},"updated_at":{"type":"string","format":"date-time","description":"When the user last changed."},"active":{"type":"boolean","description":"False for a deactivated status (inactive, disabled, suspended, deactivated; any case), true otherwise."}},"required":["id"]},"UserListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/User"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"UserResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/User"}},"required":["ok","data","requestId","apiVersion","deprecated"]},"Opportunity":{"type":"object","properties":{"name":{"type":"string","description":"The project's name."},"account_id":{"type":["string","null"],"format":"uuid","description":"The project's company (a company id in the token's workspace), or null."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The project's contact (a contact id the key can read), or null."},"manufacturers":{"type":"array","items":{"type":"string"},"description":"Manufacturer names the project is for (deduplicated); they decide its manufacturer scope."},"estimated_value":{"type":"number","description":"The estimate, in the workspace currency. Counted in the pipeline until a quote is linked."},"stage":{"type":["string","null"],"description":"The stage, as configured in the workspace's project stages."},"win_probability":{"type":["number","null"],"description":"Win % (0 to 100), or null to follow the stage's percent."},"expected_close":{"type":["string","null"],"format":"date","description":"Expected close date, YYYY-MM-DD."},"owner_user_id":{"type":["string","null"],"format":"uuid","description":"The owner (an active user in the token's workspace). A create without one is owned by the key's owner."},"source":{"type":["string","null"],"description":"Where the project came from."},"next_step":{"type":["string","null"],"description":"The next step."},"notes":{"type":["string","null"],"description":"Notes."},"lost_reason":{"type":["string","null"],"description":"Why it was lost; kept only on a move into a Lost stage, cleared on any other stage."},"lost_competitor":{"type":["string","null"],"description":"Who it was lost to; kept only with a Lost stage, like lost_reason."},"id":{"type":"string","format":"uuid","description":"The project's id."},"account":{"type":["string","null"],"description":"The company's name, copied from the company."},"contact":{"type":["string","null"],"description":"The contact's name, copied from the contact."},"closed_at":{"type":["string","null"],"format":"date-time","description":"When it was decided (Won or Lost), else null."},"created_at":{"type":"string","format":"date-time","description":"When the project was created."},"updated_at":{"type":"string","format":"date-time","description":"When the project last changed."}},"required":["id"]},"OpportunityListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/Opportunity"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"OpportunityResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Opportunity"}},"required":["ok","data","requestId","apiVersion","deprecated"]},"OpportunityWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Opportunity"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"OpportunityRestoreResult":{"type":"object","properties":{"name":{"type":"string","description":"The project's name."},"account_id":{"type":["string","null"],"format":"uuid","description":"The project's company (a company id in the token's workspace), or null."},"contact_id":{"type":["string","null"],"format":"uuid","description":"The project's contact (a contact id the key can read), or null."},"manufacturers":{"type":"array","items":{"type":"string"},"description":"Manufacturer names the project is for (deduplicated); they decide its manufacturer scope."},"estimated_value":{"type":"number","description":"The estimate, in the workspace currency. Counted in the pipeline until a quote is linked."},"stage":{"type":["string","null"],"description":"The stage, as configured in the workspace's project stages."},"win_probability":{"type":["number","null"],"description":"Win % (0 to 100), or null to follow the stage's percent."},"expected_close":{"type":["string","null"],"format":"date","description":"Expected close date, YYYY-MM-DD."},"owner_user_id":{"type":["string","null"],"format":"uuid","description":"The owner (an active user in the token's workspace). A create without one is owned by the key's owner."},"source":{"type":["string","null"],"description":"Where the project came from."},"next_step":{"type":["string","null"],"description":"The next step."},"notes":{"type":["string","null"],"description":"Notes."},"lost_reason":{"type":["string","null"],"description":"Why it was lost; kept only on a move into a Lost stage, cleared on any other stage."},"lost_competitor":{"type":["string","null"],"description":"Who it was lost to; kept only with a Lost stage, like lost_reason."},"id":{"type":"string","format":"uuid","description":"The project's id."},"account":{"type":["string","null"],"description":"The company's name, copied from the company."},"contact":{"type":["string","null"],"description":"The contact's name, copied from the contact."},"closed_at":{"type":["string","null"],"format":"date-time","description":"When it was decided (Won or Lost), else null."},"created_at":{"type":"string","format":"date-time","description":"When the project was created."},"updated_at":{"type":"string","format":"date-time","description":"When the project last changed."},"restore":{"type":"object","description":"What the restore brought back: counts only, never ids or labels. Absent on a replay whose first answer's counts could not be kept.","properties":{"restored":{"type":"object","additionalProperties":{"type":"integer","minimum":0},"description":"Restored rows per table."},"relinked":{"type":"integer","minimum":0},"skipped":{"type":"integer","minimum":0}},"required":["restored","relinked","skipped"]}},"required":["id"]},"OpportunityRestoreResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/OpportunityRestoreResult"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"AccountContactLinkResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Account"},"contact_id":{"type":"string","format":"uuid","description":"The contact linked or unlinked."},"linked":{"type":"boolean","description":"Whether the contact is linked to this company now."},"changed":{"type":"boolean","description":"false when it already was."},"warning":{"type":"string","description":"Set when the link change saved but the contact's primary company could not be updated."}},"required":["ok","data","contact_id","linked","changed","requestId","apiVersion","deprecated"]},"OpportunityQuoteLinkResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/Opportunity"},"quote_id":{"type":"string","format":"uuid","description":"The quote linked or unlinked."},"linked":{"type":"boolean","description":"Whether the quote is under this opportunity now."},"changed":{"type":"boolean","description":"false when it already was (or was not)."}},"required":["ok","data","quote_id","linked","changed","requestId","apiVersion","deprecated"]},"PrivateApiToken":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"kind":{"type":"string","enum":["key","oauth_connection"],"description":"oauth_connection: an app connected through MCP OAuth; key: a key a person made."},"scopes":{"type":"array","items":{"type":"string"}},"token_prefix":{"type":["string","null"],"description":"The key's public prefix (never the secret or its hash)."},"created_at":{"type":["string","null"],"format":"date-time","description":"When the key was made."},"last_used_at":{"type":["string","null"],"format":"date-time","description":"When the key last authenticated."},"expires_at":{"type":["string","null"],"format":"date-time","description":"When the key stops working."},"revoked_at":{"type":["string","null"],"format":"date-time","description":"When the key was revoked."},"config_version":{"type":["integer","null"],"description":"Send it as If-Match to revoke only this version of the key."},"user_id":{"type":["string","null"],"format":"uuid","description":"The key's owner."},"owner":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"user_name":{"type":["string","null"]},"email":{"type":["string","null"]}},"description":"The key's owner."},"created_by_user_id":{"type":["string","null"],"format":"uuid","description":"Who made the key."},"created_by":{"type":["object","null"],"properties":{"id":{"type":"string","format":"uuid"},"user_name":{"type":["string","null"]},"email":{"type":["string","null"]}},"description":"Who made the key."}},"required":["id"]},"PrivateApiTokenListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/PrivateApiToken"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"PrivateApiTokenResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/PrivateApiToken"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"ExpectedUpdatedAt":{"type":["string","null"],"format":"date-time","description":"The updated_at you last read."},"ExpectedEtag":{"type":["string","null"],"pattern":"^(\"[0-9a-fA-F]{32}\"|[0-9a-fA-F]{32})$","description":"The etag you last read."},"PriceSheet":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The row's id."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace."},"distributor_account_id":{"type":["string","null"],"format":"uuid","description":"The distributor company (blank: the manufacturer's base list book)."},"distributor":{"type":["string","null"],"description":"The distributor's name as entered."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer."},"manufacturer":{"type":["string","null"],"description":"The manufacturer's name as entered (a sheet needs a manufacturer: 422 otherwise)."},"name":{"type":["string","null"],"description":"The sheet's name."},"notes":{"type":["string","null"],"description":"Notes."},"created_at":{"type":"string","description":"When the row was created."},"updated_at":{"type":"string","description":"When the row last changed: what PATCH's expected_updated_at compares."}},"required":["id","workspace_id","distributor_account_id","distributor","manufacturer_id","manufacturer","name","notes","created_at","updated_at"]},"PriceSheetListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/PriceSheet"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"PriceSheetWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/PriceSheet"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"PriceSheetRow":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The row's id."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace."},"price_sheet_id":{"type":"string","format":"uuid","description":"The price sheet the row is on."},"manufacturer":{"type":["string","null"],"description":"The manufacturer as the imported file named it (descriptive only: the sheet is authoritative)."},"part_number":{"type":"string","description":"Part number (one per sheet: 409 duplicate otherwise)."},"description":{"type":["string","null"],"description":"Description."},"list_price":{"type":["number","null"],"description":"List price."},"upc":{"type":["string","null"],"description":"UPC code."},"uom":{"type":["string","null"],"description":"Unit of measure."},"weight":{"type":["number","null"],"description":"Weight."},"price_code":{"type":["string","null"],"description":"Price code (a numeric code is stored without leading zeros: \"010\" is \"10\")."},"notes":{"type":["string","null"],"description":"Notes."},"other":{"type":["string","null"],"description":"Other."},"created_at":{"type":"string","description":"When the row was created."},"updated_at":{"type":"string","description":"When the row last changed: what PATCH's expected_updated_at compares."}},"required":["id","workspace_id","price_sheet_id","manufacturer","part_number","description","list_price","upc","uom","weight","price_code","notes","other","created_at","updated_at"]},"PriceSheetRowListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/PriceSheetRow"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"PriceSheetRowWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/PriceSheetRow"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"SPA":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The row's id."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace."},"spa_number":{"type":["string","null"],"description":"SPA number (one per workspace: 409 duplicate otherwise)."},"distributor_account_id":{"type":["string","null"],"format":"uuid","description":"The distributor company."},"distributor":{"type":["string","null"],"description":"The distributor's name as entered."},"customer_account_id":{"type":["string","null"],"format":"uuid","description":"The customer company."},"customer":{"type":["string","null"],"description":"The customer's name as entered."},"manufacturer_id":{"type":["string","null"],"format":"uuid","description":"The manufacturer."},"manufacturer":{"type":["string","null"],"description":"The manufacturer's name as entered."},"price_code":{"type":["string","null"],"description":"Price code (a numeric code is stored without leading zeros: \"010\" is \"10\")."},"series_group":{"type":["string","null"],"description":"Series group."},"acc":{"type":["string","null"],"description":"ACC."},"multiplier":{"type":["number","null"],"description":"The agreement's multiplier."},"effective_date":{"type":["string","null"],"description":"Effective."},"expiration_date":{"type":["string","null"],"description":"Expires."},"notes":{"type":["string","null"],"description":"Notes."},"created_at":{"type":"string","description":"When the row was created."},"updated_at":{"type":"string","description":"When the row last changed: what PATCH's expected_updated_at compares."}},"required":["id","workspace_id","spa_number","distributor_account_id","distributor","customer_account_id","customer","manufacturer_id","manufacturer","price_code","series_group","acc","multiplier","effective_date","expiration_date","notes","created_at","updated_at"]},"SPAListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/SPA"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"SPAWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/SPA"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"ManufacturerRate":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The row's id."},"manufacturer_name":{"type":["string","null"],"description":"The manufacturer (change it in Manufacturers; read only here)."},"commission_rate":{"type":["number","null"],"description":"The default commission rate as a fraction (0.08 = 8%)."},"commission_rate_notes":{"type":["string","null"],"description":"Notes on the rate."},"updated_at":{"type":"string","description":"When the row last changed: what PATCH's expected_updated_at compares."}},"required":["id","manufacturer_name","commission_rate","commission_rate_notes","updated_at"]},"ManufacturerRateListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/ManufacturerRate"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"ManufacturerRateWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/ManufacturerRate"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"TariffSurcharge":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The row's id."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace."},"manufacturer":{"type":"string","description":"The manufacturer, by name."},"product_line":{"type":["string","null"],"description":"Product line (blank: every line)."},"price_code":{"type":["string","null"],"description":"Price code (a numeric code is stored without leading zeros: \"010\" is \"10\")."},"surcharge_pct":{"type":"number","description":"The surcharge in percent."},"includes_duty":{"type":["boolean","null"],"description":"The surcharge already passes the duty through (no duty estimate on top)."},"effective_date":{"type":["string","null"],"description":"Effective."},"expiration_date":{"type":["string","null"],"description":"Expires."},"notes":{"type":["string","null"],"description":"Notes."},"created_at":{"type":"string","description":"When the row was created."},"updated_at":{"type":"string","description":"When the row last changed: what PATCH's expected_updated_at compares."}},"required":["id","workspace_id","manufacturer","product_line","price_code","surcharge_pct","includes_duty","effective_date","expiration_date","notes","created_at","updated_at"]},"TariffSurchargeListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/TariffSurcharge"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"TariffSurchargeWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/TariffSurcharge"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"OriginDefault":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The row's id."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace."},"manufacturer":{"type":"string","description":"The manufacturer, by name."},"product_line":{"type":["string","null"],"description":"Product line (blank: every line)."},"hts_code":{"type":["string","null"],"description":"HTS code."},"country_of_origin":{"type":["string","null"],"description":"Country of origin."},"notes":{"type":["string","null"],"description":"Notes."},"created_at":{"type":"string","description":"When the row was created."},"updated_at":{"type":"string","description":"When the row last changed: what PATCH's expected_updated_at compares."}},"required":["id","workspace_id","manufacturer","product_line","hts_code","country_of_origin","notes","created_at","updated_at"]},"OriginDefaultListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/OriginDefault"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"OriginDefaultWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/OriginDefault"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"DutyRule":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"The row's id."},"workspace_id":{"type":"string","format":"uuid","description":"The workspace."},"program":{"type":"string","description":"The duty program (e.g. Section 301)."},"hts_prefix":{"type":["string","null"],"description":"HTS prefix."},"country_of_origin":{"type":["string","null"],"description":"Country of origin."},"duty_pct":{"type":"number","description":"The duty in percent."},"applies_as":{"type":["string","null"],"description":"add: on top of the HTS base rate; replace: instead of it."},"effective_date":{"type":["string","null"],"description":"Effective."},"expiration_date":{"type":["string","null"],"description":"Expires."},"notes":{"type":["string","null"],"description":"Notes."},"created_at":{"type":"string","description":"When the row was created."},"updated_at":{"type":"string","description":"When the row last changed: what PATCH's expected_updated_at compares."}},"required":["id","workspace_id","program","hts_prefix","country_of_origin","duty_pct","applies_as","effective_date","expiration_date","notes","created_at","updated_at"]},"DutyRuleListResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"type":"array","items":{"$ref":"#/components/schemas/DutyRule"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"sync":{"$ref":"#/components/schemas/SyncMetadata"}},"required":["ok","data","pagination","requestId","apiVersion","deprecated"]},"DutyRuleWriteResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"data":{"$ref":"#/components/schemas/DutyRule"},"replayed":{"type":"boolean","description":"true when this answer replays an earlier request with the same Idempotency-Key."}},"required":["ok","data","requestId","apiVersion","deprecated"]},"IndexResponse":{"type":"object","properties":{"ok":{"type":"boolean","const":true},"version":{"type":"string"},"workspaceId":{"type":"string","format":"uuid"},"requestId":{"type":"string","description":"Stable per-request identifier for support, logs, and correlation.","example":"5f9b2dc7-c130-4bb4-b7f5-47d7f2d8a1cb"},"apiVersion":{"type":"string","description":"Current private API response contract version.","example":"2026-05-01"},"deprecated":{"type":"boolean","description":"Whether this response contract is currently deprecated.","example":false},"token":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string"}},"expiresAt":{"type":["string","null"],"format":"date-time"}},"required":["id","name","scopes","expiresAt"]},"user":{"type":"object","description":"Only on a partner app's connection: the user who signed in. Absent for a key.","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"email":{"type":["string","null"]}},"required":["id","name","email"]},"endpoints":{"type":"array","items":{"type":"string"}}},"required":["ok","version","workspaceId","token","endpoints","requestId","apiVersion","deprecated"]}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Retry safely: the same key and body replay the first answer (replayed true); the same key with another body is a 409. A key is remembered for 7 days after the last call that ran with it (a replay does not extend it); after that the same key and body run again.","schema":{"type":"string","minLength":8,"maxLength":200,"pattern":"^[A-Za-z0-9._:-]+$"}},"IdempotencyKeyRequired":{"name":"Idempotency-Key","in":"header","required":true,"description":"Required (428 precondition_required without one). The same key and body replay the first answer (replayed true); the same key with another body is a 409. A key is remembered for 7 days after the last call that ran with it (a replay does not extend it); after that the same key and body run again.","schema":{"type":"string","minLength":8,"maxLength":200,"pattern":"^[A-Za-z0-9._:-]+$"}},"IfMatchConfigVersion":{"name":"If-Match","in":"header","required":false,"description":"The key's config_version: a different one is a 409 instead of a revoke; not a positive integer is a 400.","schema":{"type":"string","pattern":"^[1-9][0-9]*$"}},"IfMatchUpdatedAt":{"name":"If-Match","in":"header","required":false,"description":"The updated_at a GET returned (a W/ prefix and quotes are dropped), like expected_updated_at: a stale one is a 409. Not a timestamp: 400 invalid_if_match. Sent with an expected_updated_at naming another version: 400 if_match_mismatch.","schema":{"type":"string"}}}}}