API reference
The ax1om Scoring API takes your CRM field values and returns a fit score (0-100) and a conversion likelihood. Two endpoints, Bearer key auth, and a stable versioned contract. Mint a key in the app and make your first call in minutes.
Quickstart
- Mint a key. In the app, open Settings, API keys, then Create key. The secret (
ax1m_sk_...) is shown once. Save it. API scoring is available on Pro and above. - Grab a model_id. Any trained model in your workspace. It looks like
mdl_abc123. - POST a record. Send the fields you have. You do not need every field the model trained on.
curl -X POST https://api.ax1om.ai/v1/score \ -H "Authorization: Bearer ax1m_sk_your_key" \ -H "Content-Type: application/json" \ -d '{ "model_id": "mdl_abc123", "records": [ { "title": "VP Sales", "industry": "SaaS", "employees": 250 } ] }'You get back a fit score, a conversion likelihood, and your month-to-date usage:
{ "model_id": "mdl_abc123", "scores": [ { "score": 82, "conversion_likelihood": 0.823, "enriched": false } ], "records_scored": 1, "cache_hits": 0, "usage": { "current": 151, "limit": 10000, "remaining": 9849, "in_grace": false, "backstop": 20000 }}Authentication
Every call sends your key as a Bearer token. The webhook endpoint also accepts an X-API-Key header for CRM tools that map headers more easily. Keys start with ax1m_sk_. Treat the secret like a password: it is shown once at creation and stored only as a hash.
Authorization: Bearer ax1m_sk_your_keyTest keys
A key that starts with ax1m_sk_test_ scores against the real model but meters into a separate free bucket (1000 records/mo). It never touches your live quota and never bills. Use it to wire up and verify an integration before you flip to a live key. Test-key responses carry"test": true.
curl -X POST https://api.ax1om.ai/v1/score \ -H "Authorization: Bearer ax1m_sk_test_your_test_key" \ -H "Content-Type: application/json" \ -d '{ "model_id": "mdl_abc123", "records": [ { "title": "VP Sales" } ] }'Operations
Two endpoints, one page each. Both take the same credential and return the same error envelope.
| Method | Path | What it does |
|---|---|---|
POST | /v1/score | Batch scoring · Score records in real-time using a trained model. |
POST | /v1/webhooks/score | Webhook scoring · Score a single record via webhook. Designed for Marketo, Zapier, etc. |
Records that match your existing scored data come back enriched with a delta; unmatched records are scored from the fields you send (seeCold records).
Cold records
When you score a record that is not yet in your existing scored data, ax1om scores it from exactly the fields you send. Nothing is invented and no account matching happens on the request path. The response tells you plainly with the enriched flag:
enriched | Meaning |
|---|---|
true | The record matched your existing scored data. It carries a previous_score and delta where available. |
false | A cold record. Scored from the fields in your request only. Send richer input to get a richer score. |
The score is always real, never a placeholder. enriched: falseis a signal about input completeness, not score quality.
Errors
Every /v1 error returns the same shape. Branch onerror.code, never on the HTTP status or the message text. The codes are frozen: new ones may be added, existing ones never change.
{ "error": { "code": "invalid_api_key", "message": "API key required. Send Authorization: Bearer ax1m_sk_...", "docs_url": "https://ax1om.ai/docs/api" }}| Code | HTTP | When it fires |
|---|---|---|
invalid_api_key | 401 | Missing key, malformed key, or a revoked/unknown key. |
quota_exceeded | 429 | Scoring is paused for the month: usage passed the included limit and the grace band, and hit the hard backstop. Upgrade or contact support to resume. |
model_not_found | 404 | The model_id does not exist for your org. |
record_limit_exceeded | 400 | More than 1000 records in one batch call. |
rate_limited | 429 | Too many requests per second for the key. Slow down and retry. |
bad_request | 400 / 422 | Malformed body, no records, or a record the model could not featurize. |
internal_error | 500 | An unexpected server error. Safe to retry with backoff. |
expired_read_only | 402 | The workspace is in the post-trial read-only landing. Live scoring resumes on a paid plan; the app shows the same message. |
api_disabled | 403 | Live API is off for the score that owns this model. Turn Live API on in that score's row under Activate, then retry. |
deploy_blocked | 409 | The workspace's deploy policy is set to block and this model's validation state is not passed. Retraining is the remedy; timing models are exempt. The response carries the validation object that explains the verdict. |
Rate limits and usage
A per-key rate limit (default 10 requests/second) guards against bursts and returns rate_limited when tripped. A separate monthly metered quota counts the records you score. The monthly limit is a soft cap: live keys on a paid plan keep scoring past it in a grace band (in_grace: true, remaining goes negative) and only hard-stop with quota_exceeded at thebackstop. Test keys meter into their own free bucket with a hard cap.
Every batch response includes a usage object so you always know where you stand this month:
| Field | Type | Description |
|---|---|---|
backstop | integer | null | Hard stop for this billing month. Scoring pauses (429, code quota_exceeded) once usage reaches it. null for test keys. |
current | integer | Records scored so far this billing month, including this call. |
in_grace | boolean | true once the org is scoring past its included monthly limit, in the grace band. |
limit | integer | Monthly included scored-record limit for the plan (test keys meter into a separate free bucket). |
remaining | integer | Records left this month. Goes negative in the grace band once usage passes the included limit. |
Batch up to 1000 records per call to stay well under the rate limit.
Billing
The billable event is one scored record.POST /v1/score and POST /v1/webhooks/score meter identically: a batch of 200 records counts 200 against your monthly quota, regardless of how many API calls carried them. Every record in a successful request counts, including records tiered cold. Requests that fail return an error before any metering, so they never count.
Quotas reset each calendar month. Per plan:
| Plan | Price | Live API quota |
|---|---|---|
| Free | $0 | No Live API. Model building and insights are included free. |
| Pro | $449/mo · $400/mo billed annually ($4,800/yr) | 10K scored records/mo |
| Enterprise | From $1,500/mo, annual contract, invoice billing (NET 30) | 30K scored records/mo base, expandable by quote |
There are no usage overages, on any plan, by design. Past your quota the grace band described above keeps requests working to 2x your limit, then scoring pauses with quota_exceeded until the month resets or you upgrade. Usage can never change your bill: predictable costs are the contract. Test keys (ax1m_sk_test_) meter into their own free bucket and are never billed.
Pro starts with a 14-day trial: every Pro feature included, a payment method at checkout, no charge until day 15, cancel from the Stripe customer portal and owe nothing. Plans, tier comparison, and pricing FAQs live on thepricing page.
Versioning
The API is versioned by URL prefix (/v1). Additive changes, new response fields, new optional request fields, and new endpoints ship within/v1 without a version bump. Breaking changes, renaming or removing a field, changing a type, or changing an error code, get a new prefix, never a silent change to /v1.
Deprecated root aliases
The unversioned POST /score and POST /webhooks/scorestill work but are deprecated. They return the pre-v1 contract (the 0-1 float is named probability) and carry Deprecation: trueplus a Sunset response header (RFC 8594). Deprecated surfaces run for a minimum of 90 days. Sunset date: 2026-10-19. New integrations should use /v1, where the same value ships asconversion_likelihood and errors use the stable envelope.
| Use this | Not this (deprecated) | Sunset |
|---|---|---|
POST /v1/score | POST /score | 2026-10-19 |
POST /v1/webhooks/score | POST /webhooks/score | 2026-10-19 |
Wire it up with a test key, verify the shape, then flip to live. No SDK required, just HTTP. Mint a key ·how scoring works.