Documentation

API Reference

Everything you need to integrate with the Ambect API.

Authentication

All requests require an API key sent as a Bearer token in the Authorization header.

Authorization: Bearer en_your_api_key_here

API keys are prefixed with en_. Get a free key →

Endpoints

Base URL: https://api.ambect.com

POST
/v1/normalize/company

Normalize a company name through the full normalization pipeline.

POST
/v1/normalize/address

Parse and normalize a postal address. Optional geocoding on Growth and Business plans.

POST
/v1/normalize/phone

Parse and normalize a phone number to E.164, national, and international formats.

POST
/v1/normalize/email

Normalize an email address or URL. Detects disposable email domains.

POST
/v1/normalize/identifier

Normalize and validate a business identifier: SSN, EIN, EU VAT, SIC code, or stock ticker.

POST
/v1/normalize/batch

Normalize up to 100 entities of a single type in one request, with per-item results.

Company endpoint

Request

Send JSON with Content-Type: application/json.

POST /v1/normalize/company
{
  "name": "Berkshire Hathaway Inc.",  // required, 1–512 chars
  "country": "us"                     // optional, ISO 3166-1 alpha-2
}
FieldTypeRequiredDescription
namestringYesThe company name to normalize. Max 512 characters.
countrystringNoISO 3166-1 alpha-2 country code. Enables country-specific pipeline rules.

Response

200 OK
{
  "data": {
    "canonical": "berkshire hathaway",
    "tokens": ["berkshire", "hathaway"],
    "match_key": "berkshire hathaway",
    "legal_type": "inc"
  },
  "meta": {
    "pipeline": ["lowercase", "punctuation", "legal_suffix"],
    "country": "us",
    "confidence": 1.0,
    "ms": 1.3
  },
  "error": null
}

canonical and tokens are in processing order. match_key is the same tokens sorted alphabetically — use it to match records whose words appear in a different order (e.g. "Global Acme" and "Acme Global" share a match_key).

Pipeline stages

Runs up to 11 discrete stages. Only stages relevant to the input fire. The meta.pipeline array tells you exactly what ran.

decode

Strip control characters and HTML tags, and repair common encoding artifacts (mojibake).

unicode_norm

Apply Unicode NFC normalization.

transliterate

Convert non-Latin scripts to Latin equivalents by country.

lowercase

Normalize all characters to lowercase.

punctuation

Strip punctuation and special characters.

whitespace

Collapse and trim whitespace.

legal_suffix

Strip and record the legal entity suffix (LLC, Inc., Ltd., etc.) separately from the canonical name.

acronym_expand

Expand known acronyms to canonical long forms.

stop_words

Remove noise tokens by entity type and country.

synonym_map

Map synonyms to canonical tokens (3,000+ mappings).

dedup

Remove consecutive duplicate tokens.

Address endpoint

Request

POST /v1/normalize/address
{
  "address": "10 Downing Street, London, SW1A 2AA",  // required, 1–1024 chars
  "country": "gb",                                    // optional, ISO 3166-1 alpha-2
  "geocode": false                                    // optional, Growth+ only
}
FieldTypeRequiredDescription
addressstringYesRaw address string. Max 1,024 characters.
countrystringNoISO 3166-1 alpha-2 hint. Improves parse accuracy for ambiguous addresses.
geocodebooleanNoRequest lat/lng geocoding. Defaults to false. Requires Growth or Business plan.

Response

200 OK
{
  "data": {
    "components": {
      "building": null,
      "house_number": "10",
      "street": "Downing Street",
      "unit": null,
      "level": null,
      "staircase": null,
      "entrance": null,
      "cross_street": null,
      "suburb": "Westminster",
      "city_district": null,
      "city": "London",
      "county": null,
      "region": null,
      "country_region": null,
      "postal_code": "SW1A 2AA",
      "country": "GB"
    },
    "normalized": "10 Downing Street Westminster London SW1A 2AA GB",
    "match_key": "downing street 10 westminster london sw1a 2aa gb",
    "geocode": null
  },
  "meta": {
    "pipeline": ["validate_input", "parse", "normalize_components",
                 "country_context", "build_normalized"],
    "country": "GB",
    "confidence": 0.97,
    "ms": 2.1
  },
  "error": null
}

When geocode: true, the data.geocode object contains lat, lng, place_id, and formatted. Passing geocode: true on a Free or Starter plan returns a 403 with error.code: "geocode_tier_required".

Pipeline stages

validate_input

Check for non-empty input and validate the country hint against ISO 3166-1.

parse

Statistical address parsing via libpostal — trained on 1B+ addresses across 100+ countries and all scripts.

normalize_components

Expand street and region abbreviations, title-case all free-text fields (street, city, suburb, city district, county), and resolve country to ISO 3166-1 alpha-2.

country_context

Apply country-specific postal code formatting and validation (67 countries).

build_normalized

Assemble a canonical single-line address string and compute a match_key — stopword-stripped street tokens + house number after street + remaining components, lowercased — suitable for deduplication and fuzzy matching.

geocode

Look up lat/lng via Google Maps API. Results are cached for 30 days. Growth and Business plans only.

Phone endpoint

Request

POST /v1/normalize/phone
{
  "phone": "+1 (415) 555-0123",  // required, 1–30 chars
  "country": "US"                // optional, ISO 3166-1 alpha-2 region hint
}
FieldTypeRequiredDescription
phonestringYesRaw phone number in any format. Max 30 characters.
countrystringNoISO 3166-1 alpha-2 default region (e.g. US, GB). Required for local numbers without a country code prefix.

Response

200 OK
{
  "data": {
    "e164": "+14155550123",
    "national": "(415) 555-0123",
    "international": "+1 415-555-0123",
    "country_code": 1,
    "region": "US",
    "type": "FIXED_LINE_OR_MOBILE"
  },
  "meta": {
    "pipeline": ["validate_input", "parse", "validate_format", "format"],
    "ms": 0.8
  },
  "error": null
}

The type field reflects the ITU-T line classification: MOBILE, FIXED_LINE, FIXED_LINE_OR_MOBILE, TOLL_FREE, VOIP, PREMIUM_RATE, and others.

Pipeline stages

validate_input

Reject empty or oversized input.

parse

Parse the raw string into a structured phone number, using the country hint as the default region when no international dialling prefix is present.

validate_format

Confirm the parsed number is structurally valid for its region.

format

Produce E.164, national, and international representations; classify line type (mobile, fixed, toll-free, VoIP, etc.).

Email endpoint

Accepts an email address or URL — the type is auto-detected. Returns a normalized form plus metadata.

Request

POST /v1/normalize/email
{
  "value": "User+Tag@GMAIL.COM"  // required, 1–512 chars — email or URL
}
FieldTypeRequiredDescription
valuestringYesEmail address or URL to normalize. Max 512 characters.

Response — email

200 OK
{
  "data": {
    "normalized": "user+tag@gmail.com",
    "type": "email",
    "local": "user+tag",
    "domain": "gmail.com",
    "tld": "com",
    "disposable": false
  },
  "meta": {
    "pipeline": ["validate_input", "detect_type", "normalize", "enrich"],
    "ms": 0.5
  },
  "error": null
}

Response — URL

200 OK
{
  "data": {
    "normalized": "https://example.com/path",
    "type": "url",
    "scheme": "https",
    "host": "example.com",
    "path": "/path",
    "disposable": null
  },
  "meta": {
    "pipeline": ["validate_input", "detect_type", "normalize", "enrich"],
    "ms": 0.3
  },
  "error": null
}

Pipeline stages

validate_input

Reject empty or oversized input.

detect_type

Classify input as email or URL based on structure.

normalize

Lowercase local part and domain; strip default ports and trailing slashes from URLs.

enrich

Extract local part, domain, TLD, and flag disposable domains for emails. Runs for URLs too, but adds no fields.

Identifier endpoint

Normalizes and validates business identifiers. Supported types: us_ssn us_ein eu_vat us_sic ticker

Request

POST /v1/normalize/identifier
{
  "value": "045-85-7321",  // required, 1–64 chars
  "type": "us_ssn"         // optional — auto-detected if omitted
}
FieldTypeRequiredDescription
valuestringYesRaw identifier value. Max 64 characters.
typestringNoType hint. One of us_ssn, us_ein, eu_vat, us_sic, ticker. Auto-detected if omitted.

Response

200 OK — SSN
{
  "data": {
    "normalized": "045-85-7321",
    "type": "us_ssn",
    "valid": true,
    "country": null,
    "description": null
  },
  "meta": {
    "pipeline": ["validate_input", "detect_type", "validate_format", "format"],
    "ms": 0.4
  },
  "error": null
}
200 OK — EU VAT
{
  "data": {
    "normalized": "DE129273398",
    "type": "eu_vat",
    "valid": true,
    "country": "Germany",
    "description": null
  },
  "meta": {
    "pipeline": ["validate_input", "detect_type", "validate_format", "format"],
    "ms": 0.4
  },
  "error": null
}
200 OK — SIC code
{
  "data": {
    "normalized": "7372",
    "type": "us_sic",
    "valid": true,
    "country": null,
    "description": "Prepackaged Software"
  },
  "meta": {
    "pipeline": ["validate_input", "detect_type", "validate_format", "format"],
    "ms": 0.4
  },
  "error": null
}

Pipeline stages

validate_input

Reject empty or oversized input.

detect_type

Auto-detect identifier type (SSN, EIN, EU VAT, SIC, ticker) from structure, or accept an explicit type hint.

validate_format

Apply domain-specific validity rules (e.g. SSN area 000 invalid, EU VAT checksum must be valid for its country prefix).

format

Produce a canonical representation (e.g. dashed SSN, padded SIC, uppercase ticker) and attach contextual metadata: SIC industry description, EU VAT country name.

Batch endpoint

Normalize many entities in a single request. A batch is homogeneous — every item is the same type, and each item uses that type's request schema. Items are processed independently, so one bad item never fails the whole batch.

Request

POST /v1/normalize/batch
{
  "type": "company",                       // required — company | address | phone | email | identifier
  "items": [                               // required, 1–100 items
    { "name": "Microsoft Corporation", "country": "us" },
    { "name": "Berkshire Hathaway Inc." }
  ]
}
FieldTypeRequiredDescription
typestringYesEntity type for every item. One of company, address, phone, email, identifier.
itemsarrayYes1 to 100 objects, each matching the request schema of the chosen type (e.g. { "name", "country" } for company).

Response

Returns 200 OK with one entry per input item, in order. Each entry carries the same data, meta, and error fields the single-entity endpoint returns, plus its index.

200 OK
{
  "results": [
    {
      "index": 0,
      "data": { "canonical": "microsoft", "tokens": ["microsoft"], "match_key": "microsoft", "legal_type": "corp" },
      "meta": { "pipeline": ["lowercase", "legal_suffix"], "country": "us", "confidence": 1.0, "ms": 1.4 },
      "error": null
    },
    {
      "index": 1,
      "data": { "canonical": "berkshire hathaway", "tokens": ["berkshire", "hathaway"], "match_key": "berkshire hathaway", "legal_type": "inc" },
      "meta": { "pipeline": ["lowercase", "punctuation", "legal_suffix"], "country": null, "confidence": 1.0, "ms": 1.3 },
      "error": null
    }
  ],
  "meta": { "type": "company", "count": 2, "succeeded": 2, "failed": 0, "ms": 3.1 }
}

Partial success & validation

per-item

If an item can't be normalized, its entry has data: null and a message in error — the request still returns 200. Use meta.succeeded and meta.failed for a quick summary.

422

An empty list, more than 100 items, an unknown type, or an item missing a required field fails the whole request with 422 Validation error.

quota

Each item counts as one request against your monthly limit — a 50-item batch consumes 50. The call uses a single token against your per-second rate limit.

Rate limits

Two limits apply per API key across all endpoints. When either is exceeded, the request returns 429 Too Many Requests.

QPS (queries per second) — enforced via a token bucket with 5× burst capacity. Exceeding the sustained rate returns a Retry-After: 1 header.

Monthly cap — total requests per calendar month across all endpoints. Each item in a batch request counts as one request. See the Pricing page for overage options.

PlanQPSMonthly limitGeocoding
Free1 req/s100 req / month
Starter5 req/s2,000 req / month
Growth25 req/s15,000 req / month
Business100 req/s75,000 req / month

Errors

Two kinds of failure

Every normalization response has the same shape: data, meta, and error. A request that is well-formed but cannot be normalized — an unparseable phone number, an address the parser can't break down, an identifier of unknown type — is a normalization outcome, not a transport error. It returns 200 OK with data and meta set to null and a message in error:

200 OK
{
  "data": null,
  "meta": null,
  "error": "could not parse phone number: (1) The string supplied did not seem to be a phone number."
}

Always check the error field, not just the HTTP status. A 200 with a non-null error is a handled failure, not a success. In a batch response the same rule applies per item. The company endpoint never returns an error — it always produces a best-effort result.

The status codes below are reserved for problems with the request itself — authentication, plan limits, malformed JSON, or fields that fail schema validation:

400

Bad request — invalid or missing fields

401

Unauthorized — missing or invalid API key

403

Forbidden — feature not available on your plan

404

Not found — unknown endpoint path

422

Validation error — input failed schema checks

429

Rate limit exceeded

500

Internal server error

503

Service starting — the model is still warming up; retry shortly