chatrail-dev AI API
Optional, per connection, off by default.
Optional, per connection, off by default.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/chatrail-dev:chatrail-dev-ai-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: ChatRail AI API
version: 1.0.0
description: 'Send, schedule and receive WhatsApp messages through a linked-device session.
**Two things the API is careful about, which shape every endpoint below.**
*Accepted is not delivered.* A 202 means the message is durably stored and queued. Only the `status` field ever claims WhatsApp delivered anything, and `queued`, `submitted`, `sent`, `delivered` and `read` are deliberately distinct.
*A retry must not send twice.* Send `Idempotency-Key` on every send. A replay returns the original response; a concurrent duplicate is told to retry rather than allowed to race.'
contact:
name: ChatRail
url: https://www.chatrail.dev
servers:
- url: https://www.chatrail.dev
security:
- apiKey: []
tags:
- name: AI
description: Optional, per connection, off by default.
paths:
/v1/ai/credentials:
post:
summary: Store a model provider credential
description: Encrypted at rest and never returned. AI is off by default and enabled per connection.
tags:
- AI
operationId: post_v1_ai_credentials
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
provider:
type: string
enum:
- openai_compatible
- anthropic
label:
type: string
minLength: 1
maxLength: 80
api_key:
type: string
minLength: 8
maxLength: 8192
base_url:
type: string
format: uri
required:
- provider
- label
- api_key
additionalProperties: false
example:
provider: anthropic
label: Production key
api_key: sk-ant-replace-with-your-own-key
responses:
'201':
description: Stored.
'402':
description: AI is not on this plan.
security:
- apiKey:
- ai:write
x-scopes:
- ai:write
get:
summary: List credentials
description: Fingerprints and metadata only; the key itself is never returned.
tags:
- AI
operationId: get_v1_ai_credentials
responses:
'200':
description: Credential metadata.
security:
- apiKey:
- ai:read
x-scopes:
- ai:read
/v1/ai/credentials/{id}:
delete:
summary: Delete a credential
tags:
- AI
operationId: delete_v1_ai_credentials__id_
parameters:
- name: id
in: path
required: true
schema:
type: string
description: Credential id.
responses:
'204':
description: Deleted.
'404':
description: No such credential.
security:
- apiKey:
- ai:write
x-scopes:
- ai:write
/v1/ai/credentials/{id}/test:
post:
summary: Test a credential
description: Makes one small call to the model provider with this credential and the given model, so a wrong key or model name shows up before a customer is waiting on a reply.
tags:
- AI
operationId: post_v1_ai_credentials__id__test
parameters:
- name: id
in: path
required: true
schema:
type: string
description: Credential id.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
model:
type: string
minLength: 1
maxLength: 120
required:
- model
example:
model: openai/gpt-6-luna
responses:
'200':
description: The provider answered.
'404':
description: No such credential.
'502':
description: The provider refused or failed; the body says why.
security:
- apiKey:
- ai:write
- session: []
x-scopes:
- ai:write
/v1/ai/policies/{connection}:
put:
summary: Set the AI policy for a connection
description: Draft or auto mode, with token, rate and monthly cost ceilings. Absent policy means AI is off for that connection.
tags:
- AI
operationId: put_v1_ai_policies__connection_
parameters:
- name: connection
in: path
required: true
schema:
type: string
description: Connection slug.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
credential_source:
default: byok
type: string
enum:
- byok
- managed
credential_id:
anyOf:
- type: string
format: uuid
pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
- type: 'null'
enabled:
type: boolean
mode:
type: string
enum:
- draft
- auto
model:
type: string
minLength: 1
maxLength: 120
system_instruction:
type: string
minLength: 1
maxLength: 4000
max_context_bytes:
default: 8192
type: integer
minimum: 256
maximum: 32768
max_output_tokens:
default: 300
type: integer
minimum: 32
maximum: 2000
include_history:
default: false
type: boolean
humanize:
default: true
type: boolean
human_takeover_minutes:
default: 1440
type: integer
minimum: 0
maximum: 43200
reply_delay_seconds:
default: 5
type: integer
minimum: 0
maximum: 120
group_replies:
default: addressed
type: string
enum:
- 'off'
- addressed
- all
monthly_cost_limit_micros:
default: null
anyOf:
- type: integer
minimum: 0
maximum: 9007199254740991
- type: 'null'
input_cost_micros_per_million:
default: 0
type: integer
minimum: 0
maximum: 9007199254740991
output_cost_micros_per_million:
default: 0
type: integer
minimum: 0
maximum: 9007199254740991
required:
- enabled
- mode
- system_instruction
additionalProperties: false
example:
credential_id: 019bf4a1-0000-7000-8000-000000000000
enabled: true
mode: draft
model: claude-sonnet-4-5
system_instruction: Answer only from the attached context. If the answer is not there, say so.
responses:
'200':
description: The policy.
'402':
description: AI is not on this plan.
security:
- apiKey:
- ai:write
x-scopes:
- ai:write
get:
summary: Get the AI policy for a connection
description: Absent policy means AI is off for that connection, which is the default.
tags:
- AI
operationId: get_v1_ai_policies__connection_
parameters:
- name: connection
in: path
required: true
schema:
type: string
description: Connection slug.
responses:
'200':
description: The policy.
'404':
description: No policy is set.
security:
- apiKey:
- ai:read
x-scopes:
- ai:read
/v1/ai/runs:
get:
summary: List AI runs
description: Usage, cost, outcome and the proposed reply. The assembled prompt is represented by its hash and the list of context keys that went into it, never reproduced.
tags:
- AI
operationId: get_v1_ai_runs
responses:
'200':
description: Recent runs.
security:
- apiKey:
- ai:read
x-scopes:
- ai:read
/v1/ai/runs/{id}/send:
post:
summary: Send an AI draft
description: Accepts the pending draft through the normal durable message outbox.
tags:
- AI
operationId: post_v1_ai_runs__id__send
parameters:
- name: id
in: path
required: true
schema:
type: string
description: AI run id.
responses:
'200':
description: The accepted message id.
'409':
description: The draft cannot be sent.
security:
- apiKey:
- ai:write
x-scopes:
- ai:write
/v1/ai/runs/{id}/dismiss:
post:
summary: Dismiss an AI draft
description: 'Removes a pending draft from the human review queue without sending it. Supply a reason where you know it: the counts are what make draft quality measurable, and `wrong_correlation` in particular is the only signal that a reply was matched to the wrong alert.'
tags:
- AI
operationId: post_v1_ai_runs__id__dismiss
parameters:
- name: id
in: path
required: true
schema:
type: string
description: AI run id.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
reason:
type: string
enum:
- wrong_context
- wrong_correlation
- inaccurate
- tone
- not_needed
- needs_human
- other
additionalProperties: false
example:
reason: wrong_context
responses:
'204':
description: Dismissed.
'409':
description: The draft cannot be dismissed.
security:
- apiKey:
- ai:write
x-scopes:
- ai:write
/v1/ai/quality:
get:
summary: Summarise what happened to AI drafts
description: 'Counts only, never text: drafts sent unchanged, sent after editing, or dismissed and why; runs that ran with no business context at all; and correlation corrections grouped by the rule that originally fired. Accepts `days` (default 30).'
tags:
- AI
operationId: get_v1_ai_quality
responses:
'200':
description: The summary.
security:
- apiKey:
- ai:read
x-scopes:
- ai:read
components:
securitySchemes:
apiKey:
type: http
scheme: bearer
description: 'A workspace API key, `cr_live_…`. Server-side only: it carries workspace authority and must never reach a browser.'
session:
type: apiKey
in: cookie
name: chatrail_session
description: Dashboard session cookie. Set by `/v1/auth/verify`.