Endpoints

Base URL: https://m8tes.ai/api/v2

All requests require an API key in the Authorization header:

Authorization: Bearer m8_your_key_here

Teammates

Teammates are reusable agent personas with instructions and tools.

Create Teammate

POST /teammates

FieldTypeRequiredDescription
namestringyesName
instructionsstringnoInstructions
toolsstring[]noTool names, e.g. ['gmail', 'slack']
rolestringnoAgent persona role, e.g. 'Customer support specialist'.
goalsstringnoAgent goals. Injected into system prompt.
user_idstringnoYour end-user ID for data isolation
metadataobjectnoArbitrary key-value data
allowed_sendersstring[]noEmail addresses or @domain patterns allowed to email this teammate. Overrides default.

Response 201 Created

JSON

List Teammates

GET /teammates

ParameterTypeDescription
user_idstringFilter by end-user ID
limitintMax results (1-100, default 20)
starting_afterintCursor: last item ID

All list endpoints return a paginated envelope:

JSON

Use starting_after with the last item's ID to fetch the next page.

Get Teammate

GET /teammates/{teammate_id}

Response 200 OK

JSON

Update Teammate

PATCH /teammates/{teammate_id}

FieldTypeRequiredDescription
namestringnoName
instructionsstringnoInstructions
toolsstring[]noTools
rolestringnoRole
goalsstringnoGoals
metadataobjectnoMetadata
allowed_sendersstring[]noAllowed Senders

Response 200 OK

JSON

Delete Teammate

Soft-deletes (archives) the teammate. Returns 204 No Content.

DELETE /teammates/{teammate_id}

Enable Email Inbox

POST /teammates/{teammate_id}/email-inbox

cURL

Disable Email Inbox

DELETE /teammates/{teammate_id}/email-inbox

cURL

Runs

Runs are task executions. They stream Server-Sent Events by default.

Create Run

POST /runs

FieldTypeRequiredDescription
permission_modestringnoautonomous=auto-approve all tools, approval=pause and ask before tool use, plan=require plan approval before execution
human_in_the_loopboolnoEnable human-in-the-loop features: clarifying questions, tool approval, and plan approval. Required for non-autonomous permission modes.
teammate_idintnoTeammate Id
messagestringyesMessage
toolsstring[]noTools
streamboolnoStream
namestringnoTeammate name (creates new if no teammate_id)
instructionsstringnoTeammate instructions
user_idstringnoYour end-user ID for data isolation
metadataobjectnoArbitrary key-value data
memoryboolnoInclude saved per-user memories in agent context
historyboolnoInclude previous run results in agent context

Streaming response: Server-Sent Events

data: {"type": "text-delta", "delta": "Hello"} data: {"type": "tool-call-start", "toolName": "gmail_send", "toolCallId": "tc_1"} data: {"type": "tool-result-end", "toolCallId": "tc_1", "result": "..."} data: {"type": "done", "stop_reason": "end_turn"}

Non-streaming response 200 OK:

JSON

Polling: Non-streaming runs return immediately with status: "running". Poll GET /runs/{id} every 2 seconds until status is completed, failed, or cancelled.

Validation: permission_mode values approval and plan require human_in_the_loop=true.

Quick start: omit teammate_id and provide name to auto-create a teammate:

Python

List Runs

GET /runs

ParameterTypeDescription
teammate_idintFilter by teammate
user_idstringFilter by end-user ID
statusstringFilter by status (running, paused, awaiting_approval, completed, failed, cancelled, closed, archived)
limitintMax results (1-100, default 20)
starting_afterintCursor: last item ID

Get Run

GET /runs/{run_id}

Response 200 OK

JSON

Answer Question

POST /runs/{run_id}/answer

FieldTypeRequiredDescription
answersobjectyesMap of question text to selected option label

Use this for AskUserQuestion responses.

  • If the run is running, the answer is stored and picked up by the active run.
  • If the run is awaiting_approval, the answer resumes execution.
  • If the run is terminal (completed/failed/cancelled), the API returns 409.

Plan mode approvals use this endpoint with {"Plan Approval": "Approve"}.

Approve Permission

POST /runs/{run_id}/approve

FieldTypeRequiredDescription
request_idstringyesPermission request ID
decisionstringyesDecision
rememberboolnoRemember this decision for subsequent matching tool requests during the current run. For cross-run policies, use /permissions.
cURL

Response status: after approval this returns a resolved status (allowed or denied), not pending.

Remember behavior: remember=true applies to subsequent matching requests during the current run. For persistent cross-run allowlists, use POST /permissions.

Response 200 OK

JSON

Cancel Run

Cancel an active run. Returns 409 if the run is already completed, failed, or cancelled.

POST /runs/{run_id}/cancel

Response 200 OK

JSON

Reply To Run

Send a follow-up message on an existing run to continue the conversation.

Behavior note: runs.reply() always executes as non-interactive. It does not enable AskUserQuestion, approval, or plan mode.

POST /runs/{run_id}/reply

FieldTypeRequiredDescription
messagestringyesMessage
streamboolnoStream

List Run Permissions

Returns pending and resolved tool permission requests for runs using approval or plan mode. This list can include tool_name="AskUserQuestion" entries.

GET /runs/{run_id}/permissions

cURL

Update Permission Mode

PATCH /runs/{run_id}/permission-mode

FieldTypeRequiredDescription
permission_modestringyesPermission Mode

Tasks

Tasks are reusable job definitions. Create a task, then attach triggers via tasks.triggers.create().

Create Task

POST /tasks

FieldTypeRequiredDescription
teammate_idintyesTeammate Id
namestringnoName
instructionsstringyesInstructions
toolsstring[]noTools
expected_outputstringnoDescription of expected output format.
goalsstringnoTask-specific goals.
user_idstringnoYour end-user ID for data isolation

Response 201 Created

JSON

List Tasks

GET /tasks

ParameterTypeDescription
teammate_idintFilter by teammate
user_idstringFilter by end-user ID
limitintMax results (1-100, default 20)
starting_afterintCursor: last item ID

Get Task

GET /tasks/{task_id}

Response 200 OK

JSON

Update Task

PATCH /tasks/{task_id}

FieldTypeRequiredDescription
namestringnoName
instructionsstringnoInstructions
toolsstring[]noTools
expected_outputstringnoExpected Output
goalsstringnoGoals

Response 200 OK

JSON

Delete Task

DELETE /tasks/{task_id}

Run Task

POST /tasks/{task_id}/runs

FieldTypeRequiredDescription
permission_modestringnoautonomous=auto-approve all tools, approval=pause and ask before tool use, plan=require plan approval before execution
human_in_the_loopboolnoEnable human-in-the-loop features: clarifying questions, tool approval, and plan approval. Required for non-autonomous permission modes.
streamboolnoStream
user_idstringnoYour end-user ID for data isolation
metadataobjectnoArbitrary key-value data
memoryboolnoInclude saved per-user memories in agent context
historyboolnoInclude previous run results in agent context

Validation: permission_mode values approval and plan require human_in_the_loop=true.

Create Trigger

POST /tasks/{task_id}/triggers

FieldTypeRequiredDescription
typestringyesType
cronstringnoCron
interval_secondsintnoInterval Seconds
timezonestringnoTimezone

Response 201 Created

JSON

List Triggers

GET /tasks/{task_id}/triggers

Delete Trigger

DELETE /tasks/{task_id}/triggers/{trigger_id}


Apps

List available tools, connect integrations via OAuth, and manage end-user connections.

List Apps

Pass user_id to check connection status for a specific end-user.

GET /apps

ParameterTypeDescription
user_idstringEnd-user ID to check connections for

Connect App

POST /apps/{app_name}/connect

FieldTypeRequiredDescription
redirect_uristringyesURL to redirect after OAuth
user_idstringnoEnd-user ID for multi-tenant connections

Response 200 OK

JSON

Disconnect App

DELETE /apps/{app_name}/connections

ParameterTypeDescription
user_idstringEnd-user ID to disconnect

Connect App Complete

After the user completes OAuth and is redirected back:

POST /apps/{app_name}/connect/complete

FieldTypeRequiredDescription
connection_idstringyesConnection Id
user_idstringnoEnd-user ID for multi-tenant connections

Response 200 OK

JSON

Memories

Pre-populate or manage end-user memories. Memories are injected into the agent's context during execution to personalize responses.

Create Memory

POST /memories

FieldTypeRequiredDescription
user_idstringyesEnd-user ID this memory belongs to
contentstringyesContent

Response 201 Created

JSON

List Memories

The user_id query parameter is required.

GET /memories

ParameterTypeDescription
user_idstringEnd-user ID to list memories for
limitintMax results (1-100, default 20)
starting_afterintCursor: last item ID

Delete Memory

The user_id query parameter is required to prevent accidental deletion of account-level memories.

DELETE /memories/{memory_id}

ParameterTypeDescription
user_idstringEnd-user ID (prevents accidental deletion of account-level memories)

Permissions

Pre-configure tool allow-lists for your end-users. Tools added here are auto-approved when runs use approval mode.

Create Permission

Idempotent: re-creating the same permission returns the existing record.

POST /permissions

FieldTypeRequiredDescription
user_idstringyesEnd-user ID
toolstringyesTool name to allow, e.g. 'gmail'

Response 201 Created

JSON

List Permissions

GET /permissions

ParameterTypeDescription
user_idstringEnd-user ID to list permissions for
limitintMax results (1-100, default 20)
starting_afterintCursor: last item ID

Delete Permission

DELETE /permissions/{permission_id}

ParameterTypeDescription
user_idstringEnd-user ID (prevents accidental cross-user deletion)

Users

Manage end-user profiles. Profiles are auto-created when user_id is passed to any endpoint, or created explicitly with profile data.

Create End User

POST /users

FieldTypeRequiredDescription
user_idstringyesYour end-user identifier
namestringnoName
emailstringnoEmail
companystringnoCompany
metadataobjectnoArbitrary key-value data

Response 201 Created

JSON

List End Users

GET /users

ParameterTypeDescription
limitintMax results (1-100, default 20)
starting_afterintCursor: last item ID

Get End User

GET /users/{user_id}

Response 200 OK

JSON

Update End User

PATCH /users/{user_id}

FieldTypeRequiredDescription
namestringnoName
emailstringnoEmail
companystringnoCompany
metadataobjectnoArbitrary key-value data

Response 200 OK

JSON

Delete End User

DELETE /users/{user_id}


Settings

Account-level configuration. Control features like automatic company research.

Get Settings

GET /settings

Response 200 OK

JSON

Update Settings

PATCH /settings

FieldTypeRequiredDescription
company_researchboolnoEnable/disable automatic company research (default: enabled)

Response 200 OK

JSON

Webhooks

Register URLs to receive signed event notifications when runs change status.

Create Webhook

POST /webhooks

FieldTypeRequiredDescription
urlstringyesHTTPS URL to receive events
eventsstring[]noEvents: run.started, run.completed, run.failed, run.awaiting_input

Note: The secret is only returned on creation. Store it securely.

Response 201 Created

JSON

List Webhooks

Secrets are masked in list responses.

GET /webhooks

ParameterTypeDescription
limitintMax results (1-100, default 20)
starting_afterintCursor: last item ID

Get Webhook

GET /webhooks/{webhook_id}

Response 200 OK

JSON

Update Webhook

PATCH /webhooks/{webhook_id}

FieldTypeRequiredDescription
urlstringnoUrl
eventsstring[]noEvents
activeboolnoActive
rotate_secretboolnoGenerate a new signing secret

Response 200 OK

JSON

Delete Webhook

DELETE /webhooks/{webhook_id}

List Deliveries

View delivery attempts for a webhook endpoint.

GET /webhooks/{webhook_id}/deliveries

ParameterTypeDescription
limitintMax results (1-100, default 20)
starting_afterintCursor: last delivery ID

Errors

All errors follow a standard format:

JSON
StatusTypeSDK ExceptionDescription
400invalid_request_errorAPIErrorInvalid request
401authentication_errorAuthenticationErrorInvalid or missing API key
404not_foundNotFoundErrorResource not found
409conflict_errorAPIErrorResource conflict (duplicate, not active)
422validation_errorValidationErrorInvalid request parameters
429rate_limit_errorRateLimitErrorToo many requests (auto-retried by SDK)
500+api_errorAPIErrorServer error (auto-retried by SDK)