curl --request POST \
--url https://app.thinnest.ai/api/v1/agents/{id}/actions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"name": "get_appointment",
"description": "Look up a patient's next appointment by their phone number before answering anything about timings.",
"method": "GET",
"url": "https://api.sunrisedental.in/appointments?phone={{phone}}",
"parameters": [
{
"name": "phone",
"description": "The patient's mobile number with country code, e.g. +919876543210",
"required": true
}
],
"headers": {
"Authorization": "Bearer sk_clinic_7Hq2…"
},
"speakBefore": "One moment, let me check the diary."
}
EOFconst options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'get_appointment',
description: 'Look up a patient\'s next appointment by their phone number before answering anything about timings.',
method: 'GET',
url: 'https://api.sunrisedental.in/appointments?phone={{phone}}',
parameters: [
{
name: 'phone',
description: 'The patient\'s mobile number with country code, e.g. +919876543210',
required: true
}
],
headers: {Authorization: 'Bearer sk_clinic_7Hq2…'},
speakBefore: 'One moment, let me check the diary.'
})
};
fetch('https://app.thinnest.ai/api/v1/agents/{id}/actions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.thinnest.ai/api/v1/agents/{id}/actions"
payload = {
"name": "get_appointment",
"description": "Look up a patient's next appointment by their phone number before answering anything about timings.",
"method": "GET",
"url": "https://api.sunrisedental.in/appointments?phone={{phone}}",
"parameters": [
{
"name": "phone",
"description": "The patient's mobile number with country code, e.g. +919876543210",
"required": True
}
],
"headers": { "Authorization": "Bearer sk_clinic_7Hq2…" },
"speakBefore": "One moment, let me check the diary."
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "act_9b2f4e17-6c3a-4d81-b5e2-7a0c9d3f1e46",
"agent": "ag_3f6a9c21-7d4e-4b58-9a1f-0c2e8b7d5a34",
"name": "get_appointment",
"description": "Look up a patient's next appointment by their phone number before answering anything about timings.",
"method": "GET",
"url": "https://api.sunrisedental.in/appointments?phone={{phone}}",
"parameters": [
{
"name": "phone",
"description": "The patient's mobile number with country code, e.g. +919876543210",
"required": true
}
],
"bodyTemplate": null,
"headerNames": [
"Authorization"
],
"speakBefore": "One moment, let me check the diary.",
"speakAfter": null,
"enabled": false,
"createdAt": "2026-10-05T09:41:00.210Z",
"updatedAt": "2026-10-05T09:41:00.210Z"
}Create Action
Give the agent a call to your own API, with placeholders it fills from what the customer said. A new action is always off: test it with POST …/test, then PATCH enabled: true — sending enabled here is refused. Header values are sealed on arrival and never returned. A build key may do this.
curl --request POST \
--url https://app.thinnest.ai/api/v1/agents/{id}/actions \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"name": "get_appointment",
"description": "Look up a patient's next appointment by their phone number before answering anything about timings.",
"method": "GET",
"url": "https://api.sunrisedental.in/appointments?phone={{phone}}",
"parameters": [
{
"name": "phone",
"description": "The patient's mobile number with country code, e.g. +919876543210",
"required": true
}
],
"headers": {
"Authorization": "Bearer sk_clinic_7Hq2…"
},
"speakBefore": "One moment, let me check the diary."
}
EOFconst options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'get_appointment',
description: 'Look up a patient\'s next appointment by their phone number before answering anything about timings.',
method: 'GET',
url: 'https://api.sunrisedental.in/appointments?phone={{phone}}',
parameters: [
{
name: 'phone',
description: 'The patient\'s mobile number with country code, e.g. +919876543210',
required: true
}
],
headers: {Authorization: 'Bearer sk_clinic_7Hq2…'},
speakBefore: 'One moment, let me check the diary.'
})
};
fetch('https://app.thinnest.ai/api/v1/agents/{id}/actions', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://app.thinnest.ai/api/v1/agents/{id}/actions"
payload = {
"name": "get_appointment",
"description": "Look up a patient's next appointment by their phone number before answering anything about timings.",
"method": "GET",
"url": "https://api.sunrisedental.in/appointments?phone={{phone}}",
"parameters": [
{
"name": "phone",
"description": "The patient's mobile number with country code, e.g. +919876543210",
"required": True
}
],
"headers": { "Authorization": "Bearer sk_clinic_7Hq2…" },
"speakBefore": "One moment, let me check the diary."
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "act_9b2f4e17-6c3a-4d81-b5e2-7a0c9d3f1e46",
"agent": "ag_3f6a9c21-7d4e-4b58-9a1f-0c2e8b7d5a34",
"name": "get_appointment",
"description": "Look up a patient's next appointment by their phone number before answering anything about timings.",
"method": "GET",
"url": "https://api.sunrisedental.in/appointments?phone={{phone}}",
"parameters": [
{
"name": "phone",
"description": "The patient's mobile number with country code, e.g. +919876543210",
"required": true
}
],
"bodyTemplate": null,
"headerNames": [
"Authorization"
],
"speakBefore": "One moment, let me check the diary.",
"speakAfter": null,
"enabled": false,
"createdAt": "2026-10-05T09:41:00.210Z",
"updatedAt": "2026-10-05T09:41:00.210Z"
}Authorizations
Your API key (ta_live_…) from Settings → API keys, sent as Authorization: Bearer <key>. Keep it on a server: it can message every customer you have. A key is full, build or read-only; a request its level does not allow is refused with 403.
Headers
Developers only: the customer workspace this request acts in — its org_… id from POST /customers. Leave it out to act in your own workspace.
"org_3fKq9TzQ1mN8vB2xR7cLpA"
Path Parameters
The agent's id (ag_…).
Body
The tool name the agent sees: 3 to 40 characters, lower case letters, numbers and underscores, starting with a letter. It cannot be one of the agent's built-in tools, and must be unique on this agent.
3 - 40^[a-z][a-z0-9_]{2,39}$When the agent should call it, in a sentence (at least 10 characters). The model decides from this alone.
10An https:// address, with {{placeholders}} for parameters. Every placeholder needs a parameter of that name. Addresses inside private networks are refused when called.
2048The HTTP method; any case is accepted.
GET, POST, PUT, PATCH, DELETE Up to 20 values the agent fills from the conversation. Names must be unique.
20Show child attributes
Show child attributes
A JSON body with quoted placeholders, e.g. {"id": "{{order_id}}"}. It must still be valid JSON once the blanks are filled.
8000Up to 10 headers, name to value — typically Authorization. Write-only: sealed on arrival; only their names come back, as headerNames. Blank values are dropped.
Show child attributes
Show child attributes
On calls, what the agent says while your API is being called.
200On calls, what the agent says while it turns your answer into a reply.
200Response
The action, switched off.
The action's id (act_…).
The agent it belongs to (ag_…).
The tool name the agent sees.
When the agent should call it.
The HTTP method used.
GET, POST, PUT, PATCH, DELETE The https:// address, with {{placeholders}}.
What the agent fills in.
Show child attributes
Show child attributes
The JSON body sent, with quoted placeholders; null for none.
The names of the headers sent. Their values are write-only and never returned.
On calls, what the agent says while your API is being called.
On calls, what the agent says while it turns your answer into a reply.
Whether the agent may call it. A new action is always false.
When it was made.
When it last changed.