Documentation

Build with our API.

One bearer token. ABN capabilities your account is approved to use - text employees, workflows, agents, MCP. The same credit balance powers the web app, your scripts, your agents, and your customers' calls into our API. Your app calls ABN services; ABN handles execution behind the service boundary.

Section

Quickstart

Everything you can do in the web app you can do via the API. Same credits, same ABN employees and workflows, exposed as HTTPS endpoints under https://automatebusinessnow.com/api/v1. ABN handles execution internally; the API is service-native (e.g. image:generate), not model-native.

Use the key as an ABN app key

Your backend can use one abn_* key to power an entire application: employees, coding, images, video, voice, transcription, agents, jobs, credits, and short-lived client tokens. Call the ABN capability endpoint that matches the product action and send intent fields. ABN handles the underlying model/runtime work internally.

If a field is not documented for an ABN endpoint, do not send it. The standard app API does not accept modelId, provider, or vendorApiKey routing fields. If you are building browser or mobile flows, keep the root abn_* key on your backend and mint scoped abnct_* client tokens with /v1/tokens/mint.

// Do: call an ABN capability with intent fields.
POST /api/v1/images
Authorization: Bearer abn_YOUR_KEY_HERE
{
  "prompt": "A pixel-art mushroom on cream paper",
  "aspectRatio": "1:1",
  "quality": "high",
  "style": "illustration"
}

// Not part of the standard app API:
// modelId, provider, vendorApiKey

Your first call

The status endpoint is unauthenticated - paste it into your terminal to confirm the API is reachable from your machine.

curl https://automatebusinessnow.com/api/v1/status

You should see something like:

{
  "ok": true,
  "service": "automatebusinessnow",
  "version": "v1",
  "timestamp": "2026-04-25T00:00:00.000Z"
}

Now run a real job. Replace abn_YOUR_KEY_HERE with a key from your API keys page.

curl https://automatebusinessnow.com/api/v1/chat \
  -H "Authorization: Bearer abn_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -H "X-Request-ID: req_your_trace_id_123" \
  -d '{
    "employeeSlug": "copywriter",
    "prompt": "Visitor asks whether Detroit Auto Parts has brake pads in stock",
    "latencyProfile": "website_chat",
    "responseFormat": "plain_text",
    "stream": true
  }'

Credits & billing

Every API call deducts from the same credit balance you see at /app/credits. Failed jobs auto-refund. Plan credits refresh monthly; top-up credits never expire.

Heads-up: when a single API key burns more than 100,000 credits in 60 seconds ($1,000/min sustained), the key is auto-revoked as a safety circuit. That ceiling sits well above any legitimate single-call cost, but it stops a runaway loop dead before it bleeds your balance. Generate a new key from /app/api-keys if it ever trips. For vetted high-volume accounts we lift the cap - email hello@automatebusinessnow.com.

Section

Authentication

All /v1/* endpoints (except /v1/status) require a bearer token. You can have an unlimited number of keys per account, name them per integration, and revoke them individually.

Creating keys

Open /app/api-keys in the web app, give your key a name ("Zapier", "internal-script", etc.), and copy the resulting abn_... string. Keys are shown once at creation and never again - store them in your secret manager.

Sending the bearer

Authorization: Bearer abn_YOUR_KEY_HERE

Anything else (no header, malformed prefix, revoked key) returns 401 { "ok": false, "error": "Unauthorized" }.

Section

Async pattern - submit then poll

Every endpoint that runs a model accepts a synchronous call, but for production workloads the async submit-then-poll patternis cleaner: submit returns instantly with a job id, you poll a status endpoint until the result is ready - drop-in compatible with any poll-loop you've already written.

GET /v1/jobs/{id}

Single-shot poll. Non-blocking. Returns the current status; on completion finalizes the credit ledger atomically and returns the output URL. Subsequent polls of a completed job are idempotent - they re-read the cached terminal state, balance doesn't change.

curl https://automatebusinessnow.com/api/v1/jobs/abn_job_... \
  -H "Authorization: Bearer abn_YOUR_KEY_HERE"

While running:

{
  "ok": true,
  "jobId": "abn_job_...",
  "status": "running",
  "estimateCredits": 18,
  "createdAt": "..."
}

On completion:

{
  "ok": true,
  "jobId": "abn_job_...",
  "status": "completed",
  "outputUrl": "https://...png",
  "creditsUsed": 18,
  "balance": 18093,
  "createdAt": "...",
  "completedAt": "..."
}

On failure (credits auto-refunded):

{
  "ok": false,
  "jobId": "abn_job_...",
  "status": "failed",
  "error": "human-readable sentence",
  "creditsUsed": 0,
  "createdAt": "..."
}

Polling cadence: 4"8 seconds is plenty. Most image jobs land in 30"60s; longer agent runs vary by workflow.

You probably don't need a separate submit call.

Capability endpoints (/v1/images, /v1/voice/synthesize, /v1/voice/transcribe, /v1/agents/{id}/invoke) already return a job id when the underlying work is async - poll with the same GET /v1/jobs/{id} handler above. That covers every customer-facing integration.

Section

Endpoints

Every endpoint accepts and returns application/json. Responses are always shaped { ok, ... } on success and { ok: false, error } on failure. Customer-debuggable responses include requestId and latencyMs; send X-Request-ID if you want ABN to echo your own trace id.

GET/v1/employees

List the valid text-employee slugs accepted by /v1/chat, plus required scope and whether your key can access each one.

Request
(no body)
Response
{
  "ok": true,
  "employees": [
    {
      "slug": "copywriter",
      "name": "Copywriter",
      "scopeRequired": "employee:copywriter",
      "accessible": true,
      "responseFormats": ["markdown", "plain_text"]
    }
  ]
}
POST/v1/chat

Run a text-employee job. Use latencyProfile=website_chat for customer-facing website chat widgets.

Request
{
  "employeeSlug": "copywriter",
  "prompt": "Visitor asks whether Detroit Auto Parts has brake pads in stock",
  "imageUrl": null,
  "fileContext": null,
  "latencyProfile": "website_chat",
  "responseFormat": "plain_text",
  "stream": true
}
Response
# stream=false response
{
  "ok": true,
  "employeeSlug": "copywriter",
  "kind": "text",
  "message": "1. \"Your inbox is leaking leads...\"\n2. ...",
  "imageUrl": null,
  "executionClass": "ai",
  "latencyProfile": "website_chat",
  "responseFormat": "plain_text",
  "requestId": "req_your_trace_id_123",
  "latencyMs": 1800,
  "creditsUsed": 1,
  "balance": 18119
}

# stream=true response
Content-Type: text/event-stream

event: start
data: {"ok":true,"employeeSlug":"copywriter","latencyProfile":"website_chat","requestId":"req_..."}

event: text
data: {"delta":"Your inbox is leaking leads...","requestId":"req_..."}

event: done
data: {"ok":true,"creditsUsed":1,"balance":18119,"requestId":"req_..."}

Streaming: set stream to true or send Accept: text/event-stream. The stream emits start, text, optional stage/image, terminal done, or terminal error. For website chat, set latencyProfile to website_chat, pair it with responseFormat plain_text, display a typing state, and log requestId for support.

POST/v1/images

Generate an image with the Graphic Designer employee.

Request
{
  "prompt": "Minimalist logo for a coffee shop named Hearth",
  "aspectRatio": "1:1",
  "quality": "high",
  "style": "brand mark"
}
Response
{
  "ok": true,
  "outputUrl": "https://...png",
  "creditsUsed": 8,
  "balance": 18111
}
POST/v1/voice/synthesize

Voice-agent-grade TTS — streams audio bytes back for live voice agents.

Request
{
  "text": "Hi, thanks for calling. How can I help you today?",
  "voice": "warm-female",
  "format": "mp3",
  "model": "fast"
}
Response
Streamed audio bytes (Content-Type: audio/mpeg or audio/L16).
Headers: X-Credits-Used, X-Voice-Format.

Catalog voices: warm-female, deep-male, energetic-female,
  british-male, young-female, podcast-host.
Formats: mp3 (default) | pcm_16000 (telephony pipelines).
Models:  fast (~300ms TTFB) | quality (better prosody, slower).
Billing: 1 credit per 50 chars on fast,
         1 credit per 25 chars on quality.
POST/v1/voice/transcribe

Speech-to-text with word-level timestamps. multipart/form-data with an `audio` field. Up to 25 MB / 1 hour.

Request
# multipart/form-data
audio:    <binary mp3/wav/m4a/ogg/webm>
language: en          # optional - auto-detect if omitted
diarize:  true        # optional - speaker labels per word
Response
{
  "ok": true,
  "text": "the full transcript here",
  "words": [
    { "word": "the",  "start": 0.12, "end": 0.18 },
    { "word": "full", "start": 0.18, "end": 0.42 }
  ],
  "languageCode": "en",
  "durationSeconds": 12.4,
  "creditsUsed": 7
}

Billing: 1 credit per 2 seconds of audio (~$18/hr retail).
Migration guide

Use automatebusinessnow as the voice for your AI voice agent.

Use your abn_live_* key for TTS + STT in your voice agent. Single bearer token, single credit balance, agent-friendly streaming, and stable ABN catalog voices.

1. Synthesis (TTS)

POST https://automatebusinessnow.com/api/v1/voice/synthesize
Headers:  Authorization: Bearer abn_live_xxx
Body:     { text, voice: "warm-female", format: "mp3", model: "fast" }

Pass a catalog key (warm-female, deep-male, energetic-female, british-male, young-female, podcast-host). The response stream is byte-identical audio/mpeg or audio/L16 (PCM 16kHz). No buffering on our end; we add ~5"15ms of overhead.

2. Transcription (STT)

POST https://automatebusinessnow.com/api/v1/voice/transcribe
Headers:  Authorization: Bearer abn_live_xxx
Form:     audio=<bytes>     # field name is "audio", not "file"

Response keys are camelCase + wrapped in { ok: true, ... }: audio_duration -> durationSeconds, language_code -> languageCode.

3. Auth + billing

  • - Generate an abn_live_* key at /app/api-keys. One key for both endpoints.
  • - Keep a credit balance - TTS bills per character, STT bills per second. Credits never expire when bought as top-ups; failed jobs auto-refund.
  • - Per-key burn detection auto-revokes the key if a runaway loop drains credits unusually fast. Other keys stay live.
  • - Rate limit: 60 TTS calls/min, 20 STT calls/min by default per key. Tier upgrades scale these.
  • - Hardcoded voice settings (stability, similarity_boost, style) on synth. Custom per-call settings + WebSocket input-streaming are not exposed in v1 - open an issue if you need them.
POST/v1/agents/{id}/invoke

Invoke a configured autonomous agent on demand. The agent runs with its memory + connections, may queue work.

Request
{
  "input": "Process new leads in HubSpot from today"
}
Response
{
  "ok": true,
  "runId": "run_3a8b...",
  "status": "queued"
}
GET/v1/credits

Current credit balance for the key's owner.

Request
(no body)
Response
{
  "ok": true,
  "balance": 18121
}
GET/v1/status

Public health check. No auth required.

Request
(no body)
Response
{
  "ok": true,
  "service": "automatebusinessnow",
  "version": "v1",
  "timestamp": "2026-04-25T00:00:00.000Z"
}
Section

Rate limits

Every endpoint has a per-key rate limit. The cap scales with your plan tier - Power users get 10x the Free baseline. When you exceed it, the response is 429 Rate limit exceeded and your credits are not charged.

EndpointFree / StarterPro / ScalePower
/v1/chat30 / 60120 / 180300 rpm
/v1/images10 / 2040 / 60100 rpm
/v1/voice/synthesize20 / 4080 / 120200 rpm
/v1/voice/transcribe10 / 2040 / 60100 rpm
/v1/agents/*5 / 1020 / 3060 rpm
Section

Errors

Every error response is JSON-shaped. The HTTP status tells you the category; the error field is a stable machine code (e.g. scope_required) that your handler can switch on; the hint field is a human-readable sentence safe to surface in your UI; some errors include extra fields (e.g. scope, requiredScope, capCredits) you can use to render a tailored error or upsell.

{
  "ok": false,
  "error": "scope_required",
  "code": "scope_required",
  "message": "This key does not hold image:generate.",
  "requestId": "req_01HX...",
  "latencyMs": 14,
  "scope": "image:generate",
  "hint": "Your key isn't approved for image generation yet.",
  "upgradeUrl": "/app/api-keys"
}

HTTP status reference

StatusMeaningWhat to do
400Invalid request body / bad inputCheck the JSON shape and required fields
401Missing / bad / revoked key, or token expiredGenerate a new key or mint a fresh client token
402Insufficient creditsTop up at /app/credits - credits never expire
403Key lacks required scope or org gateSee error code below; some are unlockable via /app/billing
404Unknown employee / capability / jobCheck the slug or id against the docs above
429Rate limit exceeded or per-key cap hitBackoff and retry, or raise the cap on /app/api-keys
500Upstream model failedCredits auto-refunded; safe to retry
503Cap-check infra unavailableRetry after Retry-After header (5-10s)

Error code reference

Use the error string to branch your handler - HTTP statuses collapse several distinct conditions into a single number.

scope_requiredHTTP 403

Your key isn't approved for this capability.

Example
{
  "ok": false,
  "error": "scope_required",
  "scope": "image:generate",
  "upgradeUrl": "/app/api-keys"
}
Suggested handler

If `scope` is `image:generate`, `video:generate`, `audio:generate`, `voice:synthesize`, `voice:transcribe`, or `image:upscale`, complete verified-org promotion at /app/billing. For any other scope, recheck your key's scope list on /app/api-keys or contact hello@automatebusinessnow.com.

verified_org_requiredHTTP 403

Workflow scope needs verified-org promotion before it can be exercised.

Example
{
  "ok": false,
  "error": "verified_org_required",
  "hint": "Add a payment method or verify your domain to enable this capability.",
  "verifyUrl": "/app/billing#verify-org"
}
Suggested handler

Add a payment method at /app/billing, verify a domain via DNS-TXT, or request manual account verification from /app/billing#verify-org.

end_user_id_requiredHTTP 400

Partner keys above ~100 req/day must attribute each call to a stable end-user id.

Example
{
  "ok": false,
  "error": "end_user_id_required",
  "hint": "Send X-ABN-End-User-ID: <stable opaque id> on every call."
}
Suggested handler

Hash a stable per-end-user identifier and send it in the X-ABN-End-User-ID header. PII is never required.

end_user_id_invalidHTTP 400

The X-ABN-End-User-ID header is present but malformed (e.g. > 128 chars, control chars).

Example
{
  "ok": false,
  "error": "end_user_id_invalid",
  "hint": "End-user ids must be 1"128 printable ASCII characters."
}
Suggested handler

Hash to a fixed length (we recommend the first 32 hex chars of sha256(your-id)).

origin_not_allowedHTTP 403

A client token (abnct_*) was used from an Origin that isn't in its allowed_origins list.

Example
{
  "ok": false,
  "error": "origin_not_allowed",
  "hint": "This token cannot be called from the requesting origin."
}
Suggested handler

Mint a fresh token from your backend with the right Origin in `allowed_origins`, or call from the registered origin.

capability_unavailableHTTP 403

That ABN capability is not currently enabled for this key or account.

Example
{
  "ok": false,
  "error": "capability_unavailable",
  "capability": "image:generate",
  "hint": "This capability isn't available on your key right now."
}
Suggested handler

Use the enabled ABN capabilities on your key, or contact hello@automatebusinessnow.com if you expected this service to be active.

capability_temporarily_unavailableHTTP 503

ABN can route this capability for session callers in the live web app, but partner API keys are paused while ABN finalizes the underlying service agreement. Retry after ABN ships the agreement, or contact hello@automatebusinessnow.com for early-access updates.

Example
{
  "ok": false,
  "error": "capability_temporarily_unavailable",
  "capability": "video:generate",
  "hint": "This capability is in limited release on partner API keys while ABN finalizes the underlying service agreement."
}
Suggested handler

Honor the `Retry-After` header and retry, or reach out for early-access scheduling.

key_daily_cap_exceededHTTP 429

Today's spend on this key has crossed its `daily_credit_cap`.

Example
{
  "ok": false,
  "error": "key_daily_cap_exceeded",
  "capCredits": 5000,
  "spentToday": 5020,
  "estimate": 8
}
Suggested handler

Raise the cap on the key at /app/api-keys, or wait until the daily window rolls over (UTC midnight).

key_monthly_cap_exceededHTTP 429

This calendar month's spend on this key has crossed its `monthly_credit_cap`.

Example
{
  "ok": false,
  "error": "key_monthly_cap_exceeded",
  "capCredits": 50000,
  "spentMonth": 50020,
  "estimate": 8
}
Suggested handler

Raise the cap on the key at /app/api-keys, or wait until the calendar month rolls over.

cap_check_failedHTTP 503

The atomic cap-check RPC was momentarily unavailable. No credits were debited.

Example
{
  "ok": false,
  "error": "cap_check_failed",
  "hint": "Retry after a few seconds."
}
Suggested handler

Honor the Retry-After header (usually 5-10s) and retry. Safe - no spend occurred.

unauthorizedHTTP 401

No bearer key, bad bearer key, revoked key, expired key, or expired client token.

Example
{
  "ok": false,
  "error": "unauthorized",
  "hint": "Send Authorization: Bearer abn_... or a valid abnct_... token."
}
Suggested handler

Mint a new key at /app/api-keys or a fresh client token via /v1/tokens/mint.

unknown_employeeHTTP 404

The employeeSlug is not a valid public chat employee.

Example
{
  "ok": false,
  "error": "unknown_employee",
  "code": "unknown_employee",
  "message": "Unknown employee slug: parts-agent. Call /api/v1/employees to list valid slugs.",
  "employeeSlug": "parts-agent",
  "requestId": "req_01HX...",
  "latencyMs": 3
}
Suggested handler

Call GET /api/v1/employees and use one of the returned slugs, or build your own routing layer on top of an existing employee like customer-service.

invalid_response_formatHTTP 400

responseFormat was not markdown or plain_text.

Example
{
  "ok": false,
  "error": "invalid_response_format",
  "code": "invalid_response_format",
  "message": "responseFormat must be markdown or plain_text.",
  "requestId": "req_01HX...",
  "latencyMs": 2
}
Suggested handler

Use responseFormat="plain_text" for customer-facing chat widgets, or omit it for markdown.

invalid_latency_profileHTTP 400

latencyProfile was not standard or website_chat.

Example
{
  "ok": false,
  "error": "invalid_latency_profile",
  "code": "invalid_latency_profile",
  "message": "latencyProfile must be standard or website_chat.",
  "requestId": "req_01HX...",
  "latencyMs": 2
}
Suggested handler

Use latencyProfile="website_chat" for live widgets, or omit it for the standard employee workflow.

unsupported_routing_fieldHTTP 400

A service endpoint received a routing field it does not accept. ABN service endpoints accept documented intent fields only.

Example
{
  "ok": false,
  "error": "unsupported_routing_field",
  "fields": ["modelId"],
  "hint": "ABN service endpoints accept intent fields only."
}
Suggested handler

Drop modelId/provider/vendorApiKey fields and pass only the fields documented for the ABN endpoint.

Section

SDKs & MCP

We don't ship a vendor SDK - every endpoint is plain HTTPS JSON, so any HTTP library works. We do publish two integration surfaces for AI tools:

  • OpenAPI 3.1 spec at /api/v1/openapi- feed it to ChatGPT custom GPTs, Postman, or any tool-calling agent.
  • MCP server config for Claude Desktop, Cursor, and other MCP-aware clients. Drop the snippet into your mcp.json and your AI assistant can call us directly. See /developers for the full config.