{"openapi":"3.1.0","info":{"title":"MaestroQA External Integrations API","description":"Guides for LLM agents: [llms.md](llms.md) · [Bulk conversations](guides/bulk_conversations.md) · [Bulk datasets](guides/bulk_datasets.md)","version":"0.0.0"},"servers":[{"url":"/api/v2"}],"paths":{"/twilio/task":{"post":{"tags":["twilio"],"summary":"Post Twilio Task","operationId":"post_twilio_task_twilio_task_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwilioTask"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TwilioTask"}}}},"400":{"description":"Bad Request"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBasic":[]}]}},"/bulk_ingest/jobs/{job_id}/start":{"post":{"tags":["bulk_ingest"],"summary":"Post Job Start","description":"Call this once the file is uploaded. Sets the job to `queued` and starts processing.\n\nReturns 409 if nothing was uploaded yet or the job was already started.\nReturns 413 if the file is over 128MB.","operationId":"post_job_start_bulk_ingest_jobs__job_id__start_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestJob"}}}},"404":{"description":"Not Found"},"409":{"description":"Conflict"},"413":{"description":"Request Entity Too Large"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/bulk_ingest/jobs/{job_id}":{"get":{"tags":["bulk_ingest"],"summary":"Get Job","description":"Returns the job. Poll until `status` is `done` or `failed`. 404 if the job isn't in your account.","operationId":"get_job_bulk_ingest_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IngestJob"}}}},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/bulk_ingest/conversation_sources":{"get":{"tags":["bulk_ingest"],"summary":"Get Conversation Sources","description":"Lists your conversation sources.","operationId":"get_conversation_sources_bulk_ingest_conversation_sources_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ConversationSourceInfo"},"type":"array","title":"Response Get Conversation Sources Bulk Ingest Conversation Sources Get"}}}}}},"post":{"tags":["bulk_ingest"],"summary":"Post Conversation Source","description":"Names a conversation source. Create it before uploading with `/conversation_blocks/bulk?source=<name>`.\n\nFull guide with examples: [bulk_conversations.md](guides/bulk_conversations.md)","operationId":"post_conversation_source_bulk_ingest_conversation_sources_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationSourceInit"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationSourceInitResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/bulk_ingest/conversation_blocks/bulk":{"post":{"tags":["bulk_ingest"],"summary":"Post Conversation Blocks Bulk","description":"Creates an upload job and returns a one-time upload url, valid for 1 hour.\n\nUpload a jsonl file with one `ConversationBlock` per line, then call\n`POST /jobs/{job_id}/start`. 404 if `source` hasn't been created.\n\nFull guide with examples: [bulk_conversations.md](guides/bulk_conversations.md)","operationId":"post_conversation_blocks_bulk_bulk_ingest_conversation_blocks_bulk_post","parameters":[{"name":"source","in":"query","required":true,"schema":{"type":"string","maxLength":128,"description":"A name created with `POST /conversation_sources`.","title":"Source"},"description":"A name created with `POST /conversation_sources`."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upload"}}}},"404":{"description":"Not Found"},"429":{"description":"Too Many Requests"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/bulk_ingest/datasets":{"get":{"tags":["bulk_ingest"],"summary":"Get Datasets","description":"Lists your datasets.","operationId":"get_datasets_bulk_ingest_datasets_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/DatasetInfo"},"type":"array","title":"Response Get Datasets Bulk Ingest Datasets Get"}}}}}},"post":{"tags":["bulk_ingest"],"summary":"Post Dataset","description":"Creates a dataset. New columns are added automatically on write.\n\nLoad rows with `POST /datasets/{dataset_id}/bulk`.\n\nFull guide with examples: [bulk_datasets.md](guides/bulk_datasets.md)","operationId":"post_dataset_bulk_ingest_datasets_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetInit"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetInitResult"}}}},"400":{"description":"Bad Request"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/bulk_ingest/datasets/{dataset_id}":{"patch":{"tags":["bulk_ingest"],"summary":"Patch Dataset","description":"Renames the table, relabels or hides columns, and sets the conversation link column. Fields you leave out don't change.","operationId":"patch_dataset_bulk_ingest_datasets__dataset_id__patch","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"integer","title":"Dataset Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetEdit"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DatasetInfo"}}}},"400":{"description":"Bad Request"},"404":{"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/bulk_ingest/datasets/{dataset_id}/bulk":{"post":{"tags":["bulk_ingest"],"summary":"Post Dataset Bulk","description":"Same as `/conversation_blocks/bulk`, but for dataset rows. 404 if the dataset isn't in your account.","operationId":"post_dataset_bulk_bulk_ingest_datasets__dataset_id__bulk_post","parameters":[{"name":"dataset_id","in":"path","required":true,"schema":{"type":"integer","title":"Dataset Id"}},{"name":"format","in":"query","required":true,"schema":{"enum":["jsonl","parquet"],"type":"string","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upload"}}}},"404":{"description":"Not Found"},"429":{"description":"Too Many Requests"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Root","description":"Test endpoint for health check without authentication.","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"}}}}}}}},"components":{"schemas":{"ColumnEdit":{"properties":{"label":{"anyOf":[{"type":"string","maxLength":128,"minLength":1},{"type":"null"}],"title":"Label"},"hidden":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Hidden"}},"type":"object","title":"ColumnEdit"},"ConversationResult":{"properties":{"rows_received":{"type":"integer","title":"Rows Received"},"rows_written":{"type":"integer","title":"Rows Written"},"rejected":{"items":{"$ref":"#/components/schemas/RejectedRow"},"type":"array","title":"Rejected","description":"The first 100 rejected rows."},"table_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Table Url","description":"Opens the table in Rippit."},"source":{"type":"string","title":"Source","description":"Conversation source the conversations landed in."}},"type":"object","required":["rows_received","rows_written","source"],"title":"ConversationResult"},"ConversationSourceInfo":{"properties":{"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"columns":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Columns","description":"`searchable` keys, set from the first upload. Null until then."},"created_at":{"type":"string","format":"date-time","title":"Created At"},"table_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Table Url","description":"Opens the table in Rippit. Null until the first upload."}},"type":"object","required":["name","description","columns","created_at","table_url"],"title":"ConversationSourceInfo"},"ConversationSourceInit":{"properties":{"name":{"type":"string","maxLength":128,"minLength":1,"title":"Name","description":"Where the conversations come from, e.g. `in-app chat`. Pass it as `source` on uploads."},"description":{"type":"string","maxLength":2000,"title":"Description","default":""}},"type":"object","required":["name"],"title":"ConversationSourceInit"},"ConversationSourceInitResult":{"properties":{"name":{"type":"string","title":"Name"},"status":{"type":"string","enum":["created","exists"],"title":"Status"}},"type":"object","required":["name","status"],"title":"ConversationSourceInitResult"},"DatasetColumn":{"properties":{"column":{"type":"string","maxLength":128,"pattern":"^[a-zA-Z_][a-zA-Z0-9_]*$","title":"Column"},"type":{"type":"string","title":"Type","description":"Column type: int / float / string / bool / datetime / list<element: …>."}},"type":"object","required":["column","type"],"title":"DatasetColumn"},"DatasetEdit":{"properties":{"label":{"anyOf":[{"type":"string","maxLength":128,"minLength":1},{"type":"null"}],"title":"Label","description":"New display name for the table."},"columns":{"additionalProperties":{"$ref":"#/components/schemas/ColumnEdit"},"type":"object","title":"Columns","description":"Per column: new `label` and/or `hidden`."},"conversation_link_column":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Link Column","description":"Column holding conversation_ids; clicking a value opens that conversation. Replaces any previous link column."}},"type":"object","title":"DatasetEdit"},"DatasetInfo":{"properties":{"dataset_id":{"type":"integer","title":"Dataset Id"},"name":{"type":"string","title":"Name"},"label":{"type":"string","title":"Label","description":"Display name in Rippit. Defaults to `name`."},"description":{"type":"string","title":"Description"},"pkey_cols":{"items":{"type":"string"},"type":"array","title":"Pkey Cols"},"append_only_dataset":{"type":"boolean","title":"Append Only Dataset"},"updated_at_col":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At Col"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"table_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Table Url","description":"Opens the table in Rippit."}},"type":"object","required":["dataset_id","name","label","description","pkey_cols","append_only_dataset","updated_at_col","created_at","table_url"],"title":"DatasetInfo"},"DatasetInit":{"properties":{"name":{"type":"string","maxLength":128,"minLength":1,"title":"Name","description":"Any label, e.g. `Accounts (billing)`."},"description":{"type":"string","maxLength":2000,"title":"Description","description":"What the table holds, shown in Rippit.","default":""},"columns":{"items":{"$ref":"#/components/schemas/DatasetColumn"},"type":"array","minItems":1,"title":"Columns"},"pkey_cols":{"items":{"type":"string"},"type":"array","title":"Pkey Cols","description":"Columns that identify a row; re-uploads replace matching rows."},"append_only_dataset":{"type":"boolean","title":"Append Only Dataset","description":"Required when `pkey_cols` is empty: every uploaded row is kept.","default":false},"updated_at_col":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At Col"},"mode":{"type":"string","enum":["adhoc","ongoing"],"title":"Mode","description":"adhoc = one-off dump, ongoing = cron upserts.","default":"ongoing"}},"type":"object","required":["name","columns"],"title":"DatasetInit"},"DatasetInitResult":{"properties":{"dataset_id":{"type":"integer","title":"Dataset Id"},"status":{"type":"string","enum":["created","exists"],"title":"Status"}},"type":"object","required":["dataset_id","status"],"title":"DatasetInitResult"},"DatasetResult":{"properties":{"rows_received":{"type":"integer","title":"Rows Received"},"rows_written":{"type":"integer","title":"Rows Written"},"rejected":{"items":{"$ref":"#/components/schemas/RejectedRow"},"type":"array","title":"Rejected","description":"The first 100 rejected rows."},"table_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Table Url","description":"Opens the table in Rippit."},"dataset_id":{"type":"integer","title":"Dataset Id","description":"Dataset the rows landed in."}},"type":"object","required":["rows_received","rows_written","dataset_id"],"title":"DatasetResult"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"IngestJob":{"properties":{"job_id":{"type":"string","title":"Job Id"},"kind":{"type":"string","enum":["conversation_blocks","dataset_rows"],"title":"Kind"},"status":{"type":"string","enum":["awaiting_upload","queued","running","done","failed"],"title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"result":{"anyOf":[{"$ref":"#/components/schemas/DatasetResult"},{"$ref":"#/components/schemas/ConversationResult"},{"type":"null"}],"title":"Result","description":"Set once `done`."},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error","description":"Set once `failed`."}},"type":"object","required":["job_id","kind","status","created_at"],"title":"IngestJob"},"RejectedRow":{"properties":{"row":{"type":"integer","title":"Row","description":"0-based line or row index in the upload."},"error":{"type":"string","title":"Error"}},"type":"object","required":["row","error"],"title":"RejectedRow"},"SuccessResponse":{"properties":{"result":{"type":"string","const":"success","title":"Result"}},"type":"object","required":["result"],"title":"SuccessResponse"},"TwilioTask":{"properties":{"sid":{"type":"string","title":"Sid","description":"The unique string used to identify the Task resource."},"account_sid":{"type":"string","title":"Account Sid","description":"The SID of the Account that created the Task resource."},"workspace_sid":{"type":"string","title":"Workspace Sid","description":"The SID of the Workspace that contains the Task."},"worker_sid":{"type":"string","title":"Worker Sid","description":"The Worker SID of the agent assigned to the Task."},"date_created":{"type":"string","title":"Date Created","description":"The date and time in GMT when the resource was created specified in ISO 8601 format."},"date_updated":{"type":"string","title":"Date Updated","description":"The date and time in GMT when the resource was last updated specified in ISO 8601 format."},"call_sid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Call Sid","description":"The SID of the Call associated with the Task."},"conversation_sid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Sid","description":"The SID of the Conversation associated with the Task."},"attributes":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"string"},{"type":"null"}],"title":"Attributes","description":"The JSON object or string with custom attributes for the Task."},"age":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Age","description":"The number of seconds since the Task was created."},"assignment_status":{"anyOf":[{"type":"string","enum":["pending","reserved","assigned","canceled","wrapping","completed"]},{"type":"null"}],"title":"Assignment Status","description":"The current status of the Task's assignment."},"addons":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Addons","description":"An object that contains the addon data for all installed addons."},"task_queue_entered_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Queue Entered Date","description":"The date and time in GMT when the Task entered the TaskQueue, specified in ISO 8601 format."},"priority":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Priority","description":"The current priority score of the Task as assigned to a Worker by the workflow."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason","description":"The reason the Task was canceled or completed, if applicable."},"task_queue_sid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Queue Sid","description":"The SID of the TaskQueue."},"task_queue_friendly_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Queue Friendly Name","description":"The friendly name of the TaskQueue."},"task_channel_sid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Channel Sid","description":"The SID of the TaskChannel."},"task_channel_unique_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Channel Unique Name","description":"The unique name of the TaskChannel."},"timeout":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Timeout","description":"The number of seconds the Task can live before being assigned."},"workflow_sid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workflow Sid","description":"The SID of the Workflow that is controlling the Task."},"workflow_friendly_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workflow Friendly Name","description":"The friendly name of the Workflow that is controlling the Task."},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url","description":"The absolute URL of the Task resource."},"links":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Links","description":"The URLs of related resources."}},"type":"object","required":["sid","account_sid","workspace_sid","worker_sid","date_created","date_updated"],"title":"TwilioTask","description":"The properties of a Twilio Task.\n\nThe schema closely mirrors Twilio's definition of Task properties\n(<https://www.twilio.com/docs/taskrouter/api/task#task-properties>)\nwith the additions of `worker_sid`, `call_sid`, and `conversation_sid`."},"Upload":{"properties":{"job_id":{"type":"string","title":"Job Id"},"upload_url":{"type":"string","title":"Upload Url","description":"Presigned S3 POST. Send `requests.post(upload_url, data=upload_fields, files={'file': f})`."},"upload_fields":{"additionalProperties":{"type":"string"},"type":"object","title":"Upload Fields","description":"Form fields that must go with the file, unchanged."},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"max_bytes":{"type":"integer","title":"Max Bytes","description":"S3 rejects larger files with 400 EntityTooLarge.","default":134217728}},"type":"object","required":["job_id","upload_url","upload_fields","expires_at"],"title":"Upload"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"HTTPBasic":{"type":"http","scheme":"basic"}}}}