chatrail-dev AI API

Optional, per connection, off by default.

Operations 10

POST /v1/ai/credentials Store a model provider credential #
GET /v1/ai/credentials List credentials #
DELETE /v1/ai/credentials/{id} Delete a credential #
POST /v1/ai/credentials/{id}/test Test a credential #
PUT /v1/ai/policies/{connection} Set the AI policy for a connection #
GET /v1/ai/policies/{connection} Get the AI policy for a connection #
GET /v1/ai/runs List AI runs #
POST /v1/ai/runs/{id}/send Send an AI draft #
POST /v1/ai/runs/{id}/dismiss Dismiss an AI draft #
GET /v1/ai/quality Summarise what happened to AI drafts #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • 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.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/chatrail-dev:chatrail-dev-ai-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

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 Specification

chatrail-dev-ai-api-openapi.yml Raw ↑
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`.