EmailmoversMyDataHub docs
Browse the docs

Platform

Errors

The 26 problem types the API returns, each with its HTTP status and what to do next.

Generated from the contractsView as Markdown

Every error is an RFC 9457 problem with the media type application/problem+json. Its type is a URI under https://emailmovers.com/mydatahub/docs/errors/, and each of the pages below is that URI.

Two members go beyond the RFC: next_step says what to do, and did_you_mean lists the closest valid values. MCP tool errors reuse the same object with isError true. The text content leads with the sentence a person acts on, followed by the whole problem as JSON.

Problem types

CodeHTTPTitleNext step
invalid-request400The request could not be readSend a JSON body with Content-Type: application/json and check the query string.
idempotency-key-required400An Idempotency-Key header is requiredSend an Idempotency-Key header (a V4 UUID is a good choice) and reuse it on every retry.
unsupported-version400Unsupported MyDataHub-VersionSend a MyDataHub-Version date the API lists, such as 2027-01-15, or leave it out.
authentication-required401Sign in or send an API keySend Authorization: Bearer with an mdh_ API key. Sign-in through https://mydatahub.emailmovers.com/id is planned.
account-required401This needs a free accountCreate a free account (100 credits, no card) for single company counts, more than 6 filters in one audience, free text title search or a radius under 5 miles. Free and trial accounts still see rounded small counts; exact figures come with a paid plan.
insufficient-credits402Not enough creditsTop up at the top_up_url, then retry with the same machine quote_id (or the same enrichment request).
insufficient-scope403The token lacks a scopeAsk the user to approve the scope named in required_scope, then retry.
confirmation-required403A person must confirm this spendNothing was charged. Keep the machine quote_id and give the user the approval_url; retry with the confirmation_token it returns, or use an agent key whose limits cover the spend.
business-details-required403Business details are needed before the first orderNothing was charged. A person who owns the account confirms the business name and that it is a UK business, in the app's Settings or with PATCH /v1/account, then the same machine quote_id is ordered again.
licence-acceptance-required403The data licence agreement must be acceptedNothing was charged. A person accepts the version in force (the account's agreements.dlsa): by ticking the box on the quote or at approval_url, where they can also approve this spend, or, for an agent key that orders or enriches on its own, on the key. Then the same request is sent again.
dpa-acceptance-required403The data processing agreement must be acceptedNothing was uploaded. A person who owns the account accepts the Article 28 data processing agreement at the version in force (the account's agreements.dpa): in the app's Settings, with the box on the app's first upload, or with POST /v1/account/agreements. Then the same list is uploaded again.
agent-budget-exceeded403The agent key budget does not cover this spendKeep the machine quote_id and ask the key owner to approve it at approval_url, or top up at top_up_url.
not-found404Not foundCheck the id; ids are prefixed, such as ord_ for orders and aud_ for audiences.
method-not-allowed405Method not allowedUse a method named in the Allow header; every path starts /v1 and /v1/openapi.json lists them.
idempotency-key-reused409Idempotency-Key reused with different parametersUse a new Idempotency-Key for a different request; reuse a key only to retry.
quote-expired409The machine quote has expiredCall quote_order (POST /v1/quotes) again; a machine quote is valid for 24 hours.
order-not-ready409The order is not readyWait for the order.ready webhook, or poll GET /v1/orders/{id} until status is ready.
order-not-cancellable409Only a queued order can be cancelledRecords already delivered stay under licence; report bounces for a warranty claim.
validation-failed422The request is not validFix each entry in errors, using did_you_mean where given, and send it again.
quote-required422A machine quote is requiredCall quote_order first; a machine quote is valid for 24 hours.
dataset-unavailable422The dataset is not served yetUse uk_contacts; GET /v1/datasets shows when other datasets open.
rate-limited429Too many requestsWait for the seconds in Retry-After, then retry.
internal-error500Something went wrong on our sideNothing was charged. Retry with the same Idempotency-Key; if it persists, quote the instance to support.
not-implemented501Not implemented yetUse the operations that answer today; /v1/openapi.json lists every operation and how it is declared.
service-unavailable503The service is briefly unavailableWait for the seconds in Retry-After, then retry with the same Idempotency-Key. The status page shows incidents.
tps-screen-expired503The TPS and CTPS screen is more than 28 days oldNothing was charged. Email-only audiences carry on, with a field set without telephone and no phone. filter or breakdown. Telephone audiences return once a new dataset version is published; GET /v1/health shows the screen's age.

Reading a problem

{
  "type": "https://emailmovers.com/mydatahub/docs/errors/validation-failed",
  "title": "The request is not valid",
  "status": 422,
  "detail": "Unknown field company.employees.",
  "instance": "/v1/counts",
  "code": "validation-failed",
  "next_step": "Fix each entry in errors, using did_you_mean where given, and send it again.",
  "did_you_mean": ["company.employee_band"],
  "errors": [
    {
      "pointer": "/audience/where/all/0/field",
      "code": "invalid_value",
      "message": "Unknown field company.employees.",
      "did_you_mean": ["company.employee_band"]
    }
  ]
}

Branch on code, never on detail or title, which are for people and may be reworded. A problem that spends nothing says so in next_step. A 4xx response never charges credits, and an order retried with the same Idempotency-Key is never charged twice.

Every response, errors included, carries the RateLimit and RateLimit-Policy headers. A 429 and a 503 also carry Retry-After. See Rate limits.