Ellon AI API

Build on the same tools that power ellon.ai โ€” translate, redact, compare, and analyze documents programmatically.

Base URL
https://www.ellon.ai/api/v1
Auth header
X-API-Key
Version
v1 (stable)
01

Authentication

Every request to the public API must include an X-API-Key header carrying a personal API key. Keys are created and revoked from the Settings โ†’ API Keys tab. API key creation requires the Starterplan or higher โ€” free-trial accounts can view the tab but must upgrade before issuing their first key.

Keys are prefixed with wga_ followed by 32 hexadecimal characters. The full secret is shown once at creation time โ€” store it in a secrets manager or environment variable, never in source control.

bash
curl https://www.ellon.ai/api/v1/subscriptions/me \
  -H "X-API-Key: $ELLON_API_KEY"

Scope:v1 keys inherit the full permissions of the owning user and have no scoping โ€” treat every key as if it could read or mutate any resource in the account. Scoped keys are on the roadmap.

02

Rate limits

Rate limits are applied per API key and vary by subscription tier. Each response carries the standard slowapi throttling headers so clients can self-regulate:

  • X-RateLimit-Limit โ€” The active quota for the current window
  • X-RateLimit-Remaining โ€” Requests remaining before throttling kicks in
  • X-RateLimit-Reset โ€” Unix timestamp when the window resets
  • Retry-After โ€” Seconds to wait after a 429 response
PlanTier keyPer minutePer hour
Free Trialfree_trial10100
Starterstarter301,000
Professionalprofessional603,000
Businessbusiness12010,000

When a key exceeds its window, the API returns 429 Too Many Requests with error code rate_limit_exceeded. Rate limits are a burst-protection mechanism and are separate from monthly plan usage caps (see Plan enforcement below).

03

Plan enforcement

The public API is metered against the same monthly allowances (pages, files, characters) as the web application. Translation, redaction, compare, and clause-analysis requests are billed against your subscription tier or consume available credits exactly as they do in the UI.

When a request would exceed the plan allowance, the API returns 429 Too Many Requests with error code plan_limit_exceeded and a structured details object containing the feature name, the usage so far, and the configured limit:

json
{
  "error": {
    "code": "plan_limit_exceeded",
    "message": "Monthly translation page limit reached. Used 1200/1000 pages this billing period.",
    "details": {
      "feature": "translation",
      "used": 1200,
      "limit": 1000
    }
  }
}

See Pricing for the per-tier allowances, or call GET /api/v1/subscriptions/usage programmatically to check your current utilization.

04

Errors

Every error returned by the public API uses the same envelope, regardless of which endpoint or middleware produced it:

json
{
  "error": {
    "code": "<stable_identifier>",
    "message": "<human-readable message>",
    "details": <optional object with structured info>
  }
}

error.code is a stable string you can branch on. The list of codes the public API emits today:

CodeHTTPMeaning
bad_request400Malformed request
unauthorized401Missing or invalid API key
forbidden403Key is valid but not allowed for this resource
not_found404Resource does not exist
method_not_allowed405HTTP verb not supported on this path
conflict409Resource state conflict
payload_too_large413Upload or body exceeds size limit
unsupported_media_type415Content-Type not accepted
validation_error422Request body failed schema validation
rate_limit_exceeded429Per-key request rate exceeded
plan_limit_exceeded429Monthly plan allowance exceeded for this feature
internal_error500Unhandled server error
bad_gateway502Upstream dependency failed
service_unavailable503Service temporarily unavailable
gateway_timeout504Upstream dependency timed out

Note: rate_limit_exceeded and plan_limit_exceeded both return HTTP 429, but they mean different things. Rate-limit errors indicate burst abuse and will clear within seconds; plan-limit errors indicate the account has consumed its monthly allowance and will not clear until the next billing cycle or a plan upgrade.

Example: resource not found.

json
{
  "error": {
    "code": "not_found",
    "message": "Redaction job not found.",
    "details": null
  }
}

Example: validation failure with per-field detail.

json
{
  "error": {
    "code": "validation_error",
    "message": "Request validation failed",
    "details": {
      "errors": [
        {
          "type": "missing",
          "loc": ["body", "document_id"],
          "msg": "Field required",
          "input": null
        }
      ]
    }
  }
}
05

Endpoints: Documents

Upload a document before running a translation, redaction, compare, or analysis operation. Documents are the primary input resource for every processing feature in the API.

POST/documents/uploadUpload a document: DOCX, PDF, DOC, PPTX, IDML, MD, or TEX file (multipart form).
GET/documents/historyList uploaded documents for the authenticated user.
GET/documents/{document_id}Fetch metadata for a single document.
DELETE/documents/{document_id}Soft-delete a document and its derived files.
bash
curl https://www.ellon.ai/api/v1/documents/upload \
  -H "X-API-Key: $ELLON_API_KEY" \
  -F "file=@contract.pdf"
06

Endpoints: Translation jobs

Translate a previously-uploaded document into any supported target language. Jobs run asynchronously โ€” create, poll for completion, then download the translated result.

POST/translation-jobsCreate a translation job.
POST/translation-jobs/estimateEstimate token cost before committing.
GET/translation-jobsList translation jobs.
GET/translation-jobs/{job_id}Poll job status and progress.
GET/translation-jobs/{job_id}/downloadDownload the translated file.
GET/translation-jobs/{job_id}/download-pdfDownload the translated file as PDF.
POST/translation-jobs/{job_id}/stopHalt a running job.
POST/translation-jobs/{job_id}/resumeResume a stopped job.
DELETE/translation-jobs/{job_id}Delete a job and its artifacts.
bash
# 1. Create the job
curl https://www.ellon.ai/api/v1/translation-jobs \
  -H "X-API-Key: $ELLON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_id": "8f1c9d42-4b6e-4c8a-9f3d-1e2a7b6c5d4f",
    "target_language": "fr",
    "output_format": "single",
    "column_to_keep": "translated"
  }'

# 2. Poll status until "status": "completed"
curl https://www.ellon.ai/api/v1/translation-jobs/$JOB_ID \
  -H "X-API-Key: $ELLON_API_KEY"

# 3. Download the result
curl https://www.ellon.ai/api/v1/translation-jobs/$JOB_ID/download \
  -H "X-API-Key: $ELLON_API_KEY" \
  -o translated.docx
07

Endpoints: Redaction jobs

Redaction is a multi-step state machine: detect PII, review the detected entities, confirm which ones to redact, then download the redacted output. The redaction_style field accepts blackbar, label, or pseudonym.

POST/redaction-jobsCreate a job and start PII detection.
GET/redaction-jobsList redaction jobs.
GET/redaction-jobs/{job_id}Poll detection status and fetch detected entities.
PATCH/redaction-jobs/{job_id}/entitiesAdjust which entities to include or exclude.
POST/redaction-jobs/{job_id}/confirmConfirm entity selection and begin redaction.
GET/redaction-jobs/{job_id}/downloadDownload the redacted document.
GET/redaction-jobs/{job_id}/download-pdfDownload the redacted document as PDF.
GET/redaction-jobs/{job_id}/redaction-logDownload the audit log of what was redacted.
DELETE/redaction-jobs/{job_id}Delete a job and its artifacts.
bash
# 1. Kick off detection
curl https://www.ellon.ai/api/v1/redaction-jobs \
  -H "X-API-Key: $ELLON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_id": "8f1c9d42-4b6e-4c8a-9f3d-1e2a7b6c5d4f",
    "redaction_style": "blackbar",
    "language": "en"
  }'

# 2. Poll until detected_entities is populated
curl https://www.ellon.ai/api/v1/redaction-jobs/$JOB_ID \
  -H "X-API-Key: $ELLON_API_KEY"

# 3. Confirm the selection and run the redaction
curl https://www.ellon.ai/api/v1/redaction-jobs/$JOB_ID/confirm \
  -H "X-API-Key: $ELLON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"selected_entity_ids": ["e_1","e_2","e_3"]}'

# 4. Download the redacted file
curl https://www.ellon.ai/api/v1/redaction-jobs/$JOB_ID/download \
  -H "X-API-Key: $ELLON_API_KEY" \
  -o redacted.docx
08

Endpoints: Compare jobs

Submit two documents (an original and a revised version) and receive a tracked-changes redline as output. Optionally enable semantic analysis to get an AI summary of the substantive differences.

POST/compare-jobsCreate a comparison between two documents.
GET/compare-jobsList compare jobs.
GET/compare-jobs/{job_id}Poll job status.
GET/compare-jobs/{job_id}/downloadDownload the redlined document.
GET/compare-jobs/{job_id}/download-pdfDownload the redlined document as PDF.
DELETE/compare-jobs/{job_id}Delete a job and its artifacts.
bash
curl https://www.ellon.ai/api/v1/compare-jobs \
  -H "X-API-Key: $ELLON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "original_document_id": "8f1c9d42-4b6e-4c8a-9f3d-1e2a7b6c5d4f",
    "revised_document_id": "2d7a8b93-1f4c-4a6d-b8e5-5c3f9a1d6e2b",
    "enable_semantic_analysis": true
  }'
09

Endpoints: Clause analysis

Analyze a contract for clause-level risk, plain-language summaries, and missing-clause detection. Pass an optional jurisdiction and contract_type to tailor the analysis.

POST/analysis-jobsCreate a clause-analysis job.
GET/analysis-jobsList analysis jobs.
GET/analysis-jobs/{job_id}Poll job status and fetch structured results.
GET/analysis-jobs/{job_id}/downloadDownload the raw JSON analysis payload.
GET/analysis-jobs/{job_id}/download-pdfDownload a formatted PDF report.
DELETE/analysis-jobs/{job_id}Delete a job and its artifacts.
bash
curl https://www.ellon.ai/api/v1/analysis-jobs \
  -H "X-API-Key: $ELLON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "document_id": "8f1c9d42-4b6e-4c8a-9f3d-1e2a7b6c5d4f",
    "jurisdiction": "uk",
    "contract_type": "nda",
    "language": "en"
  }'
10

Endpoints: Affiliate outreach

Programmatic access to the affiliate outreach workspace. Requires the affiliate role on your account โ€” apply at /affiliate. Non-members receive 404 (not 403) on every route, so the surface stays invisible to the general user base.

Typical automation flow: create a campaign, bulk-add recipients, check quota, trigger generation, edit drafts, mark-contacted, archive. Drafts stay server-side so the same automation can resume across runs.

Campaigns

GET/outreach/campaignsList your non-archived campaigns.
POST/outreach/campaignsCreate a campaign with name + context.
GET/outreach/campaigns/{id}Full detail including recipients and drafts.
PATCH/outreach/campaigns/{id}Update name, context, or status.
DELETE/outreach/campaigns/{id}Archive a campaign (soft delete).

Recipients

POST/outreach/campaigns/{id}/recipientsBulk-add up to 500 recipients per campaign.
PATCH/outreach/campaigns/{id}/recipients/{rid}Update any recipient field.
DELETE/outreach/campaigns/{id}/recipients/{rid}Hard-delete a recipient and its draft.
POST/outreach/campaigns/{id}/recipients/{rid}/mark-contactedFlip status to contacted + record timestamp.

Drafts & generation

POST/outreach/campaigns/{id}/generateRun the LLM for ready recipients (10/min burst, daily quota).
PUT/outreach/campaigns/{id}/recipients/{rid}/draftPersist a manual edit to the draft.
GET/outreach/quotaToday's quota snapshot (limit, used, remaining, reset).
POST/outreach/check-statusCross-campaign suppression check, scoped to caller.

Example: end-to-end automation

bash
# 1. Create a campaign
CAMPAIGN_ID=$(curl -s https://www.ellon.ai/api/v1/outreach/campaigns \
  -H "X-API-Key: $ELLON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Q3 law firms โ€” DACH",
    "context": {
      "affiliate_link": "https://ellon.ai?ref=$YOUR_CODE",
      "prospect_context": "Mid-size law firms in Germany with active translation pipelines",
      "target_market": "Germany ยท DACH",
      "target_role": "Partner ยท Managing Director",
      "pain_points": "Slow turnaround on multi-language contract reviews",
      "tone": "warm",
      "language": "en",
      "cta_style": "soft",
      "email_length": "short"
    }
  }' | jq -r .id)

# 2. Pre-flight the suppression check (optional)
curl -s https://www.ellon.ai/api/v1/outreach/check-status \
  -H "X-API-Key: $ELLON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"emails": ["anna@kanzlei-beispiel.de", "marc@law-example.de"]}'

# 3. Add recipients (server flags existing Ellon users as "protected")
curl -s "https://www.ellon.ai/api/v1/outreach/campaigns/$CAMPAIGN_ID/recipients" \
  -H "X-API-Key: $ELLON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "recipients": [
      {"email": "anna@kanzlei-beispiel.de", "first_name": "Anna", "company": "Kanzlei Beispiel"},
      {"email": "marc@law-example.de", "first_name": "Marc", "company": "Law Example"}
    ]
  }'

# 4. Check quota before spending tokens
curl -s https://www.ellon.ai/api/v1/outreach/quota \
  -H "X-API-Key: $ELLON_API_KEY"

# 5. Generate drafts for every recipient with status="ready"
curl -s "https://www.ellon.ai/api/v1/outreach/campaigns/$CAMPAIGN_ID/generate" \
  -H "X-API-Key: $ELLON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"recipient_ids": []}'

# 6. Mark a recipient as contacted after you send
curl -s -X POST \
  "https://www.ellon.ai/api/v1/outreach/campaigns/$CAMPAIGN_ID/recipients/$RID/mark-contacted" \
  -H "X-API-Key: $ELLON_API_KEY"

Errors & guardrails

  • 404on any route if you don't have the affiliate role, or on campaigns/recipients you don't own. Never 403 โ€” we deliberately hide the surface.
  • 429 on /generate when the daily quota would be exceeded. Response body carries limit, used, remaining, reset_at. A separate 10/min burst cap also applies.
  • 409 on bulk-add when a concurrent insert collides on the (campaign_id, email) uniqueness โ€” rare, retriable.
  • Recipients with status protected (existing Ellon customer) are server-set and can't be overridden via the API. They are silently skipped by /generate.
11

Endpoints: Credits & subscription

Read-only endpoints that expose the caller's current credit balance, recent transactions, active subscription, and monthly usage. These do not mutate billing state โ€” purchases and upgrades still happen in the web app.

GET/credits/balanceCurrent remaining credit balance.
GET/credits/transactionsRecent credit debits and top-ups.
GET/subscriptions/meThe authenticated user&apos;s active subscription.
GET/subscriptions/tiersPublicly available subscription tiers and pricing.
GET/subscriptions/usageCurrent-cycle usage vs. plan allowance.
GET/subscriptions/usage/historyHistorical usage by billing cycle.
bash
curl https://www.ellon.ai/api/v1/subscriptions/usage \
  -H "X-API-Key: $ELLON_API_KEY"
11

OpenAPI & SDKs

The full machine-readable OpenAPI 3 specification describes every public endpoint, every request and response schema, and every error code emitted by the API. Use it to generate a typed client in any language with openapi-generator, openapi-ts, or the tool of your choice.

bash
# Example: generate a TypeScript client
npx @hey-api/openapi-ts \
  --input https://www.ellon.ai/api/public/openapi.json \
  --output ./src/ellon-client
12

Changelog

v1.0.02026-04-15

Initial public release. All document processing features โ€” translate, redact, compare, and analyze โ€” are available via API with a unified authentication, rate-limiting, and error envelope.