curl --request POST \
--url https://api.pomerado.ai/v1/api-keys \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Nightly price check",
"permissions": [
"tools:read",
"runs:create",
"jobs:read"
],
"integration_id": "int_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190",
"expires_in_days": 30,
"deliver": "dashboard"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Nightly price check',
permissions: ['tools:read', 'runs:create', 'jobs:read'],
integration_id: 'int_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190',
expires_in_days: 30,
deliver: 'dashboard'
})
};
fetch('https://api.pomerado.ai/v1/api-keys', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.pomerado.ai/v1/api-keys"
payload = {
"name": "Nightly price check",
"permissions": ["tools:read", "runs:create", "jobs:read"],
"integration_id": "int_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190",
"expires_in_days": 30,
"deliver": "dashboard"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"dashboard_url": "<string>"
}{
"id": "key_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190",
"name": "Nightly price check",
"permissions": [
"tools:read",
"runs:create",
"jobs:read"
],
"integration_id": "int_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190",
"prefix": "pom_0f8e2d1c",
"created_via": "dashboard",
"created_at": "2026-10-05T18:30:00.000Z",
"expires_at": "2026-10-05T18:30:00.000Z",
"last_used_at": "2026-10-05T18:30:00.000Z",
"secret": "pom_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190_example-secret-not-a-real-key-0000000000000"
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}Create an API key
Create an API key and return its secret once. Send the secret as a Bearer token on the REST API or any Pomerado MCP. A key carries only permissions you hold now; without permissions it carries all of them except api_keys:manage, which a key needs to manage keys. It expires after 90 days unless expires_in_days says otherwise. With deliver “dashboard”, nothing is created yet: the answer is a Dashboard link where the person creates the key and sees the secret, so it never reaches this client.
curl --request POST \
--url https://api.pomerado.ai/v1/api-keys \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Nightly price check",
"permissions": [
"tools:read",
"runs:create",
"jobs:read"
],
"integration_id": "int_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190",
"expires_in_days": 30,
"deliver": "dashboard"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Nightly price check',
permissions: ['tools:read', 'runs:create', 'jobs:read'],
integration_id: 'int_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190',
expires_in_days: 30,
deliver: 'dashboard'
})
};
fetch('https://api.pomerado.ai/v1/api-keys', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.pomerado.ai/v1/api-keys"
payload = {
"name": "Nightly price check",
"permissions": ["tools:read", "runs:create", "jobs:read"],
"integration_id": "int_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190",
"expires_in_days": 30,
"deliver": "dashboard"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"dashboard_url": "<string>"
}{
"id": "key_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190",
"name": "Nightly price check",
"permissions": [
"tools:read",
"runs:create",
"jobs:read"
],
"integration_id": "int_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190",
"prefix": "pom_0f8e2d1c",
"created_via": "dashboard",
"created_at": "2026-10-05T18:30:00.000Z",
"expires_at": "2026-10-05T18:30:00.000Z",
"last_used_at": "2026-10-05T18:30:00.000Z",
"secret": "pom_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190_example-secret-not-a-real-key-0000000000000"
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}{
"error": {
"code": "<string>",
"message": "<string>",
"retryable": true,
"docs_url": "<string>",
"details": {}
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
1 to 100 characters, without leading or trailing spaces
1 - 100^\S(?:.*\S)?$"Nightly price check"
Permissions the key carries, each one you hold now. Default: every permission you hold except api_keys:manage
1 - 16 elementstools:read, usage:read, tools:build, runs:create, jobs:read, jobs:cancel, connections:read, credentials:manage, api_keys:manage ["tools:read", "runs:create", "jobs:read"]
Bind the key to one integration: it then runs only that integration's tools, and carries only tools:read, runs:create, jobs:read and jobs:cancel
"int_0f8e2d1c4b3a49e8a7f6e5d4c3b2a190"
Days until the key expires, 1 to 365 (default 90)
1 <= x <= 36530
Answer a Dashboard link instead of the secret, so the secret never reaches this client
dashboard Response
With deliver dashboard: where to finish
A signed-in Dashboard page where the person finishes this and sees the secret once