Endpoints
All endpoints require a valid API key. See Authentication for details on creating and using API keys.
- All response bodies use camelCase field names. Timestamps are ISO 8601 strings in UTC unless noted otherwise.
- All query parameters use camelCase (e.g.
sourceId,remoteId,createdAfter). - Each endpoint requires either the
reador theingestscope (see Authentication for the full mapping); GETs useread, POST / PATCH / DELETE useingest. - Request bodies for POST / PATCH endpoints are limited to 10 MB and require a
Content-Lengthheader. - Records you push into Sybill are uniquely identified by
(sourceId, remoteId)(whereremoteIdis theidyou supplied at create time). ThesourceIdmust reference a source you created viaPOST /v1/sources.
On GET /v1/conversations, /v1/messages, /v1/rows, and /v1/documents, the sourceId query parameter is polymorphic — it accepts either:
- the UUID of a source you created via
POST /v1/sources, or - a reserved native string identifying a built-in Sybill origin (e.g.
gong,gmail,salesforce_crm,chat_upload).
The same sourceId value appears on every read response item so you can round-trip filters. The reserved native strings per resource are listed under each endpoint below.
Health check
Verify your API key is valid and inspect its scopes. Requires any valid API key.
Response:
{
"status": "ok",
"org_id": "550e8400-e29b-41d4-a716-446655440000",
"scopes": ["read", "ingest"]
}
Conversations
Returns a paginated list of conversations in your organization. Requires the read scope. Cursor-paginated.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Number of results per page (1–50) |
startedAfter | string (ISO 8601) | — | Lower bound for meeting start time |
startedBefore | string (ISO 8601) | — | Upper bound for meeting start time |
type | string | — | Filter by meeting type: INTERNAL or EXTERNAL |
title | string | — | Filter by conversation title (case-insensitive partial match) |
attendees | string | — | Filter by participant: name fragment, full email, or company domain (@acme.com) |
crmName | string | — | Filter by associated CRM deal/account name (case-insensitive exact-phrase) |
sourceId | string | — | Filter by conversation origin. Accepts either a source UUID or a reserved native meeting-provider string: sybill, gong, chorus, fathom, grain, mindtickle, avoma, fireflies, zoho_meetings, uploaded_call, uploaded_transcript, sdk_upload, zoom_phone, outreach_dialer. |
cursor | string | — | Pagination cursor from a previous response |
Response:
{
"conversations": [
{
"conversationId": "550e8400-e29b-41d4-a716-446655440000",
"sourceId": "gong",
"title": "Q4 Pipeline Review",
"startTime": "2023-11-14T22:13:20Z",
"endTime": "2023-11-15T00:13:20Z",
"type": "EXTERNAL",
"participants": [
{ "name": "Jane Smith", "email": "jane@example.com", "attended": true }
],
"crm": { "id": "006...", "name": "Acme Deal", "type": "opportunity" }
}
],
"pagination": {
"nextCursor": "eyJzZWFyY2hBZnRlciI6...",
"hasMore": true
}
}
See Pagination for details on iterating through results.
Returns the full detail for a single conversation, including transcript, recordings, and AI-generated summary. Requires the read scope.
Path parameters:
| Parameter | Type | Description |
|---|---|---|
conversationId | UUID | The conversation identifier |
Response:
{
"conversationId": "550e8400-e29b-41d4-a716-446655440000",
"sourceId": "gong",
"title": "Q4 Pipeline Review",
"startTime": "2023-11-14T22:13:20Z",
"endTime": "2023-11-15T00:13:20Z",
"type": "EXTERNAL",
"category": "prospect_negotiation",
"participants": [
{ "name": "Jane Smith", "email": "jane@example.com", "attended": true }
],
"crm": { "id": "006...", "name": "Acme Deal", "type": "opportunity" },
"recordings": {
"videoUrl": "https://recordings.example.com/meeting.mp4?...",
"audioUrl": "https://recordings.example.com/meeting.mp3?..."
},
"transcript": [
{ "speaker": "Jane Smith", "text": "Let's review the pipeline numbers.", "startTime": 0.0, "endTime": 4.5 }
],
"summary": {
"Outcome": "Deal moved to negotiation stage.",
"Pain Points": ["Integration complexity", "Timeline concerns"]
}
}
Errors:
| Status | Meaning |
|---|---|
404 Not Found | Conversation does not exist or is not accessible to your organization |
Push a conversation (transcript and/or recording) into Sybill. Requires the ingest scope. Returns 201 Created.
The body must include a non-empty transcript array, a recordingUrl, or both. Provide a recording URL when you want Sybill to transcribe and enrich the audio/video; provide a transcript when you already have one.
Request body: ConversationRequest.
{
"id": "external-conv-123",
"sourceId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"displayName": "Acme onboarding call",
"createdAt": "2024-05-01T15:00:00Z",
"startedAt": "2024-05-01T15:00:00Z",
"endedAt": "2024-05-01T15:45:00Z",
"participants": [
{ "email": "alice@acme.com", "name": "Alice Smith" },
{ "email": "rep@sybill.ai", "name": "Sales Rep" }
],
"recordingUrl": "https://example.com/recording.mp4",
"ownerEmails": ["rep@sybill.ai"]
}
Response: RecordResponse.
Errors:
| Status | Meaning |
|---|---|
400 Bad Request | Validation error (e.g. missing transcript and recording URL, malformed timestamp) |
403 Forbidden | Source belongs to another organization or is otherwise inaccessible |
409 Conflict | Concurrent write of the same record |
411 Length Required | Missing Content-Length header |
413 Payload Too Large | Request body exceeds 10 MB |
Soft-delete a conversation you previously pushed via POST /v1/conversations. Requires the ingest scope.
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
remoteId | string | yes | Your external identifier (the id you supplied at create time) |
sourceId | UUID | yes | The source the record was created under |
Response: DeletedRecordResponse.
Deals
Returns a paginated list of CRM deals in your organization. Requires the read scope. Cursor-paginated.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Number of results per page (1–50) |
name | string | — | Filter by deal name (case-insensitive partial match) |
stage | string | — | Filter by pipeline stage name (case-insensitive partial match) |
closed | boolean | — | Filter by closed status (true for won/lost, false for open) |
owner | string | — | Filter by deal owner name (case-insensitive partial match) |
closeDateAfter | string (ISO 8601) | — | Lower bound for close date |
closeDateBefore | string (ISO 8601) | — | Upper bound for close date |
amountMin | number | — | Minimum deal amount |
amountMax | number | — | Maximum deal amount |
lastActivityAfter | string (ISO 8601) | — | Lower bound for last activity date |
lastActivityBefore | string (ISO 8601) | — | Upper bound for last activity date |
cursor | string | — | Pagination cursor from a previous response |
Response:
{
"deals": [
{
"dealId": "006ABC000000123456",
"name": "Acme Enterprise Deal",
"accountName": "Acme Corp",
"stage": "Negotiation",
"pipeline": "Sales Pipeline",
"amount": 50000.0,
"closeDate": "2024-03-15T00:00:00Z",
"closed": false,
"createdDate": "2023-09-01T10:30:00Z",
"lastActivityDate": "2024-01-10T15:30:00Z",
"owner": { "name": "Jane Doe", "email": "jane@example.com" }
}
],
"pagination": {
"nextCursor": "eyJ0cyI6MTcwMDAwMDAwMDAwMCwiaWQi...",
"hasMore": true
}
}
Returns the full detail for a single deal, including AI-generated summary, CRM autofill suggestions, and contacts. Requires the read scope.
Path parameters:
| Parameter | Type | Description |
|---|---|---|
dealId | string | The CRM remote identifier of the deal |
Response:
{
"dealId": "006ABC000000123456",
"name": "Acme Enterprise Deal",
"accountName": "Acme Corp",
"stage": "Negotiation",
"pipeline": "Sales Pipeline",
"amount": 50000.0,
"closeDate": "2024-03-15T00:00:00Z",
"closed": false,
"createdDate": "2023-09-01T10:30:00Z",
"lastActivityDate": "2024-01-10T15:30:00Z",
"owner": { "name": "Jane Doe", "email": "jane@example.com" },
"summary": {
"Current Status": "Deal is progressing well through negotiation.",
"Pain Points": ["Budget constraints", "Timeline pressure"]
},
"crmAutofill": {
"Next Steps": "Schedule follow-up call with legal team"
},
"contacts": [
{ "name": "John Smith", "email": "john@acme.com", "title": "VP Sales", "phone": "+1234567890" }
]
}
Errors:
| Status | Meaning |
|---|---|
404 Not Found | Deal does not exist or is not accessible to your organization |
Accounts
Returns a paginated list of CRM accounts in your organization. Requires the read scope. Cursor-paginated.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 20 | Number of results per page (1–50) |
name | string | — | Filter by account name (case-insensitive partial match) |
website | string | — | Filter by website URL (case-insensitive partial match) |
owner | string | — | Filter by owner name or email (case-insensitive partial match) |
createdAfter | string (ISO 8601) | — | Lower bound for created date |
createdBefore | string (ISO 8601) | — | Upper bound for created date |
lastActivityAfter | string (ISO 8601) | — | Lower bound for last activity date |
lastActivityBefore | string (ISO 8601) | — | Upper bound for last activity date |
cursor | string | — | Pagination cursor from a previous response |
Response:
{
"accounts": [
{
"accountId": "001ABC000000123456",
"name": "Acme Corp",
"website": "https://acme.com",
"owner": { "name": "Jane Doe", "email": "jane@example.com" },
"createdDate": "2023-09-01T10:30:00Z",
"lastActivityDate": "2024-01-10T15:30:00Z",
"latestDeal": {
"dealId": "006ABC000000789012",
"name": "Acme Enterprise Deal",
"stage": "Negotiation",
"amount": 50000.0,
"closeDate": "2024-03-15T00:00:00Z"
}
}
],
"pagination": {
"nextCursor": "eyJ0cyI6MTcwMDAwMDAwMDAwMCwiaWQi...",
"hasMore": true
}
}
Returns the full detail for a single account, including contacts and synced CRM fields. Requires the read scope.
Path parameters:
| Parameter | Type | Description |
|---|---|---|
accountId | string | The CRM remote identifier of the account |
Response:
{
"accountId": "001ABC000000123456",
"name": "Acme Corp",
"website": "https://acme.com",
"owner": { "name": "Jane Doe", "email": "jane@example.com" },
"createdDate": "2023-09-01T10:30:00Z",
"lastActivityDate": "2024-01-10T15:30:00Z",
"latestDeal": {
"dealId": "006ABC000000789012",
"name": "Acme Enterprise Deal",
"stage": "Negotiation",
"amount": 50000.0,
"closeDate": "2024-03-15T00:00:00Z"
},
"contacts": [
{ "name": "John Smith", "email": "john@acme.com", "title": "VP Sales", "phone": "+1234567890" }
],
"syncedCrmFields": {
"Industry": "Technology",
"Annual Revenue": "$10M"
}
}
Errors:
| Status | Meaning |
|---|---|
404 Not Found | Account does not exist or is not accessible to your organization |
Messages
Returns a paginated list of messages in your organization. Requires the read scope. Cursor-paginated.
The unified read API surfaces all message origins through one shape: native email/CRM integrations (Gmail, Outlook, Zoho Mail, Salesforce/HubSpot/Pipedrive/Dynamics/Zoho CRMs) and any messages you push via POST /v1/messages.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
sourceId | string | — | Filter by message origin (UUID of a source you created, or a native string: gmail, outlook, zoho_mail, salesforce_crm, hubspot_crm, pipedrive_crm, dynamics_crm, zoho_crm) |
remoteId | string | — | Filter by upstream message identifier (provider-assigned id) |
threadId | string | — | Filter to messages in a single thread |
participantEmail | string | — | Filter to messages where this email appears as sender or recipient |
createdAfter | string (ISO 8601) | — | Lower bound for source-system creation time |
createdBefore | string (ISO 8601) | — | Upper bound for source-system creation time |
cursor | string | — | Pagination cursor from a previous response |
limit | integer | 50 | Number of results per page (1–50) |
Response:
{
"messages": [
{
"messageId": "9b9f7c2c-2d8e-4a17-9d6e-1234567890ab",
"sourceId": "gmail",
"remoteId": "1812af3b9...",
"threadId": "thread-42",
"subject": "Re: Demo follow-up questions",
"sender": { "name": "Alice Smith", "email": "alice@acme.com" },
"recipients": [
{ "name": "Sales Rep", "email": "rep@sybill.ai" }
],
"bodyPreview": "Thanks for the demo yesterday — a few follow-up questions...",
"createdAt": "2024-05-01T15:00:00Z"
}
],
"pagination": {
"nextCursor": "eyJ0cyI6MTcxNzAwMDAwMDAwMCwiaWQi...",
"hasMore": true
}
}
Returns the full detail for a single message, including its body and attachment metadata. Requires the read scope.
Path parameters:
| Parameter | Type | Description |
|---|---|---|
messageId | UUID | Sybill message identifier |
Response:
{
"messageId": "9b9f7c2c-2d8e-4a17-9d6e-1234567890ab",
"sourceId": "gmail",
"remoteId": "1812af3b9...",
"threadId": "thread-42",
"subject": "Re: Demo follow-up questions",
"sender": { "name": "Alice Smith", "email": "alice@acme.com" },
"recipients": [
{ "name": "Sales Rep", "email": "rep@sybill.ai" }
],
"bodyPreview": "Thanks for the demo yesterday — a few follow-up questions...",
"createdAt": "2024-05-01T15:00:00Z",
"body": "Thanks for the demo yesterday. We're moving forward with...",
"attachments": [
{
"id": "0a3e2c8a-5d51-4d2f-8d6c-9be0b9f3e2d4",
"filename": "questions.pdf",
"contentType": "application/pdf",
"size": 12345
}
]
}
Errors:
| Status | Meaning |
|---|---|
400 Bad Request | Message source is not supported by this endpoint |
404 Not Found | Message does not exist or is not accessible to your organization |
Push a message into Sybill. Requires the ingest scope. Returns 201 Created.
Request body: MessageRequest.
{
"id": "msg-9001",
"sourceId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"displayName": "Re: Pricing question",
"createdAt": "2024-05-01T15:00:00Z",
"body": "Hi Alice, here is the updated pricing sheet...",
"sender": { "email": "rep@sybill.ai", "name": "Sales Rep" },
"recipients": [
{ "email": "alice@acme.com", "name": "Alice Smith" }
],
"attachments": [
{ "name": "pricing.pdf", "url": "https://example.com/pricing.pdf", "mimeType": "application/pdf" }
],
"threadId": "thread-42"
}
Response: RecordResponse.
Errors: Same as POST /v1/conversations.
Soft-delete a message you previously pushed via POST /v1/messages. Requires the ingest scope.
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
remoteId | string | yes | Your external identifier (the id you supplied at create time) |
sourceId | UUID | yes | The source the record was created under |
Response: DeletedRecordResponse.
Rows
Rows are structured records keyed by an object type. Use them to store CRM-like custom data (tickets, leads, forms) that is neither a conversation nor a message.
Returns a paginated list of rows in your organization. Requires the read scope. Cursor-paginated.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
sourceId | string | — | UUID of a source you created. (Rows have no native origins; only UUID values are accepted.) |
objectTypeId | UUID | — | Filter to rows of a single object type |
remoteId | string | — | Filter by the id you supplied at create time |
name | string (≤1000) | — | Filter by row name (case-insensitive partial match) |
createdAfter | string (ISO 8601) | — | Lower bound for source-system creation time |
createdBefore | string (ISO 8601) | — | Upper bound for source-system creation time |
cursor | string | — | Pagination cursor from a previous response |
limit | integer | 50 | Number of results per page (1–50) |
Response:
{
"rows": [
{
"rowId": "9b9f7c2c-2d8e-4a17-9d6e-1234567890ab",
"sourceId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"objectTypeId": "0a3e2c8a-5d51-4d2f-8d6c-9be0b9f3e2d4",
"objectTypeName": "support_ticket",
"remoteId": "TKT-1234",
"name": "Login bug — Acme",
"displayName": "Login bug — Acme",
"fields": {
"priority": { "value": "high", "fieldType": "string", "label": "Priority" },
"openedAt": { "value": "2024-05-01T15:00:00Z", "fieldType": "datetime" }
},
"createdAt": "2024-05-01T15:00:00Z",
"updatedAt": null
}
],
"pagination": {
"nextCursor": "eyJ0cyI6MTcxNzAwMDAwMDAwMCwiaWQi...",
"hasMore": true
}
}
Returns a single row by its Sybill identifier. The shape is identical to a list item — rows are simple enough that detail and list views match. Requires the read scope.
Path parameters:
| Parameter | Type | Description |
|---|---|---|
rowId | UUID | Sybill row identifier |
Errors:
| Status | Meaning |
|---|---|
404 Not Found | Row does not exist or is not accessible to your organization |
Create a row. Requires the ingest scope. The objectTypeId must already exist (create one via POST /v1/object-types). Each fields value carries an explicit fieldType that must match the object type's schema.
Request body: RowRequest.
{
"id": "TKT-1234",
"sourceId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"objectTypeId": "0a3e2c8a-5d51-4d2f-8d6c-9be0b9f3e2d4",
"displayName": "Login bug — Acme",
"name": "TKT-1234",
"fields": {
"priority": { "value": "high", "fieldType": "string", "label": "Priority" },
"openedAt": { "value": "2024-05-01T15:00:00Z", "fieldType": "datetime" },
"score": { "value": 87, "fieldType": "int" }
}
}
Response: RecordResponse.
Apply a partial update to an existing row. Requires the ingest scope.
The fields map merges per RFC 7396: keys present overwrite existing values, keys absent are preserved, and an explicit null value deletes that key from the row. Top-level fields (displayName, name, public, ownerEmails, updatedAt) are not nullable — passing null is silently ignored.
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
remoteId | string | yes | Your external identifier |
sourceId | UUID | yes | The source the record was created under |
Request body: UpdateRowRequest.
{
"displayName": "Login bug — Acme (escalated)",
"fields": {
"priority": { "value": "urgent", "fieldType": "string" },
"score": null
}
}
Response: RecordResponse.
Errors:
| Status | Meaning |
|---|---|
400 Bad Request | Validation error (unknown field, type mismatch, deleting a required field) |
403 Forbidden | Source or row belongs to another organization |
404 Not Found | Row not found for (sourceId, remoteId) |
Soft-delete a row. Requires the ingest scope.
Query parameters: Same as PATCH /v1/rows.
Response: DeletedRecordResponse.
Documents
Documents are arbitrary text-bearing artifacts (PDFs, plain-text notes, web pages, etc.) you push into Sybill, plus documents created by native chat uploads.
Returns a paginated list of documents in your organization. Requires the read scope. Cursor-paginated.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
sourceId | string | — | Filter by document origin (UUID of a source you created, or the native string chat_upload) |
name | string (≤255) | — | Case-insensitive partial match on displayName |
cursor | string | — | Pagination cursor from a previous response |
limit | integer | 50 | Number of results per page (1–50) |
Response:
{
"documents": [
{
"id": "9b9f7c2c-2d8e-4a17-9d6e-1234567890ab",
"displayName": "Acme onboarding plan",
"sourceId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"remoteId": "doc-42",
"url": "https://example.com/doc.pdf",
"contentType": "application/pdf",
"createdAt": "2024-05-01T15:00:00Z",
"updatedAt": "2024-05-02T10:00:00Z"
}
],
"pagination": {
"nextCursor": "eyJ0cyI6MTcxNzAwMDAwMDAwMCwiaWQi...",
"hasMore": true
}
}
Returns the full detail for a single document, including links to Sybill's processed text representation when available. Requires the read scope.
Path parameters:
| Parameter | Type | Description |
|---|---|---|
documentId | UUID | Sybill document identifier |
Response:
{
"id": "9b9f7c2c-2d8e-4a17-9d6e-1234567890ab",
"displayName": "Acme onboarding plan",
"sourceId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"remoteId": "doc-42",
"url": "https://example.com/doc.pdf",
"contentType": "application/pdf",
"createdAt": "2024-05-01T15:00:00Z",
"updatedAt": "2024-05-02T10:00:00Z",
"normalizedUrl": "https://normalized.example.com/doc-42.txt",
"normalizedContentType": "text/plain"
}
Errors:
| Status | Meaning |
|---|---|
400 Bad Request | Document source is not supported by this endpoint |
404 Not Found | Document does not exist or is not accessible to your organization |
Create a document. Requires the ingest scope. Returns 201 Created.
Provide exactly one of:
url— Sybill fetches the document from this URL.content— base64-encoded document bytes embedded in the request.
Request body: DocumentRequest.
{
"id": "doc-42",
"sourceId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"displayName": "Acme onboarding plan",
"url": "https://example.com/doc.pdf",
"contentType": "application/pdf",
"author": { "email": "rep@sybill.ai", "name": "Sales Rep" }
}
Response: RecordResponse.
Apply a partial update to an existing document. Requires the ingest scope.
You may pass at most one of url / content. Supplying either creates a new version and reprocesses the document. A PATCH with neither performs a metadata-only update (e.g. rename, change owners). author is intentionally not updatable — delete and recreate if you need to change it.
Query parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
remoteId | string | yes | Your external identifier |
sourceId | UUID | yes | The source the record was created under |
Request body: UpdateDocumentRequest.
{
"displayName": "Acme onboarding plan (v2)",
"url": "https://example.com/doc-v2.pdf"
}
Response: RecordResponse.
Soft-delete a document. Requires the ingest scope.
Query parameters: Same as PATCH /v1/documents.
Response: DeletedRecordResponse.
Sources
A source is a logical channel that records you push into Sybill belong to (e.g. "Zendesk", "Sales Notes", "Internal Wiki"). All POST / PATCH / DELETE endpoints on /v1/conversations, /v1/messages, /v1/rows, and /v1/documents require a sourceId referring to a source you own. Read endpoints additionally accept reserved native source strings — see each endpoint above for the catalog.
Create a new source. Requires the ingest scope. The name is a stable machine identifier and must be unique within your organization; displayName is shown in the Sybill UI.
Request body: CreateSourceRequest.
{ "name": "internal-wiki", "displayName": "Internal Wiki" }
Response: SourceResponse.
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "internal-wiki",
"displayName": "Internal Wiki",
"createdAt": "2024-05-01T15:00:00Z",
"updatedAt": "2024-05-01T15:00:00Z"
}
Errors:
| Status | Meaning |
|---|---|
400 Bad Request | Validation error |
409 Conflict | A source with the same name already exists in your organization |
List sources in your organization. Requires the read scope.
Query parameters:
| Parameter | Type | Description |
|---|---|---|
name | string (≤255) | Optional case-insensitive partial match on source name |
Response:
{
"sources": [
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "internal-wiki",
"displayName": "Internal Wiki",
"createdAt": "2024-05-01T15:00:00Z",
"updatedAt": "2024-05-01T15:00:00Z"
}
]
}
Fetch a single source. Requires the read scope.
Response: SourceResponse.
Rename a source. Requires the ingest scope. Only displayName can be changed; name is immutable.
Request body: UpdateSourceRequest.
{ "displayName": "Internal Wiki (Confluence)" }
Response: SourceResponse.
Delete a source. Requires the ingest scope.
Response:
{ "status": "deleted", "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479" }
Object types
An object type defines the shape of /v1/rows records. It declares a name, a display name, and a list of typed field definitions.
Create an object type within a source. Requires the ingest scope.
Request body: CreateObjectTypeRequest.
{
"sourceId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "support_ticket",
"displayName": "Support Ticket",
"fieldDefinitions": [
{ "name": "priority", "fieldType": "string", "label": "Priority", "required": true },
{ "name": "openedAt", "fieldType": "datetime", "label": "Opened at" },
{ "name": "score", "fieldType": "int" }
]
}
fieldType must be one of the values listed under FieldTypes.
Response: ObjectTypeResponse.
Errors:
| Status | Meaning |
|---|---|
400 Bad Request | Validation error (e.g. duplicate field names) |
409 Conflict | An object type with the same name already exists under the source |
List object types in your organization. Requires the read scope.
Query parameters:
| Parameter | Type | Description |
|---|---|---|
sourceId | UUID | Optional — restrict results to a single source |
Response:
{
"objectTypes": [
{
"id": "0a3e2c8a-5d51-4d2f-8d6c-9be0b9f3e2d4",
"sourceId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"name": "support_ticket",
"displayName": "Support Ticket",
"fieldDefinitions": [
{ "name": "priority", "fieldType": "string", "label": "Priority", "required": true }
],
"createdAt": "2024-05-01T15:00:00Z",
"updatedAt": "2024-05-01T15:00:00Z"
}
]
}
Fetch a single object type. Requires the read scope.
Response: ObjectTypeResponse.
Update an object type. Requires the ingest scope. Both displayName and fieldDefinitions are optional; supplying fieldDefinitions replaces the full schema.
Request body: UpdateObjectTypeRequest.
Response: ObjectTypeResponse.
Delete an object type. Requires the ingest scope.
Response:
{ "status": "deleted", "id": "0a3e2c8a-5d51-4d2f-8d6c-9be0b9f3e2d4" }
Common error responses
All endpoints may return these errors:
| Status | Meaning |
|---|---|
400 Bad Request | Malformed request, validation error, or invalid query parameter |
401 Unauthorized | Missing, invalid, or revoked API key |
403 Forbidden | API key lacks the required scope, or the resource belongs to another organization |
404 Not Found | Resource does not exist or is not accessible to your organization |
409 Conflict | Concurrent or duplicate write |
411 Length Required | A POST / PATCH endpoint received a request without a Content-Length header |
413 Payload Too Large | A POST / PATCH endpoint received a request body larger than 10 MB |
422 Unprocessable Entity | Request validation failed |
429 Too Many Requests | Rate limit exceeded (see Rate Limiting) |
500 Internal Server Error | Unexpected server error |
POST / PATCH / DELETE endpoints return errors with a structured body:
{
"detail": {
"error": "validation_error",
"message": "exactly one of url or content must be provided",
"field": null,
"request_id": "01HV..."
}
}
GET endpoints generally return errors as { "detail": "<message>" }.