EmailmoversMyDataHub docs
Browse the docs

Guide

Quotes and orders

A machine quote prices a count for 24 hours at 0 credits. An order spends credits against that quote and delivers records under a 12 month licence.

Updated 4 October 2026View as Markdown

You pay once, for a complete UK record, at 1 credit each. A machine quote tells you the price before you commit, costs nothing and lasts 24 hours, and an order spends credits against it. Quoting and ordering use the same objects in the app, over REST and over MCP.

Two kinds of quote

Whenever the word quote appears, it is one of two objects.

Machine quoteHuman sales quote
Made byPOST /v1/quotes, quote_orderThe app, or an account manager
Lasts24 hours14 days
FormJSON, signed ES256, bound to a dataset versionA PDF, payable by card or invoice link
Used forOrdering by API, agent or appBuying without an account, or sharing with a colleague
Idqte_ with kind machineqte_ with kind sales

Both share the qte_ prefix. The rest of this page is about the machine quote.

Make a quote

Count first, then quote the count. A quote is free and needs no account.

{
  "count_id": "cnt_7K2PQ4MAXN3R6TBY5WDZ",
  "field_set": "standard",
  "limit": 5000,
  "dedupe_against": "previous_orders",
  "licence": "multi_use_12m"
}
MemberMeaning
count_idA count from POST /v1/counts. Either case is accepted
field_setA field set id from GET /v1/field-sets. Every field set costs 1 credit a record
limitRecords to buy. Left out, the whole count
dedupe_againstnone, previous_orders, crm or previous_orders_and_crm. The CRM options need a connection_id
licencemulti_use_12m, or outright (proposed, 1.8 credits a record)

Records you already hold under licence are always left out of a quote, whatever dedupe_against says. The value only adds the CRM overlap check.

Read a quote

This response is abridged.

{
  "id": "qte_01JB4M2R6T1Y5W8ZAK8Q2V7XN3",
  "kind": "machine",
  "records": 5000,
  "removed": { "already_held": 312, "suppressed": 41 },
  "credits_required": 5000,
  "credits_available": 6200,
  "gbp_ex_vat": 1495,
  "licence": { "type": "multi_use_12m", "reuse_until": "2027-09-26", "resale_prohibited": true },
  "warranty": { "policy": "replace_over_threshold_hard_bounce" },
  "expires_at": "2026-09-27T10:14:00Z",
  "blockers": []
}
  • records is what you would receive, after overlap and suppression. removed records are never charged.
  • credits_available and balance_after need an account. They are null when signed out, and balance_after is negative when you need a top-up.
  • blockers lists why the quote cannot be ordered yet: insufficient_credits, account_required, agent_budget_exceeded, dataset_unavailable or count_expired.
  • signature is an ES256 JWS over the quote's price, so one agent can hand a quote to another and both can check it against the key at jwks_url.

A quote made without an account is taken by the first organisation that orders it, and is then priced again on that organisation's own records and lists. The order charges the smaller of the quote and what that organisation can still be sold.

Credits

One credit buys one complete UK record: a named email, a telephone number where held, a postal address and company fields including the Companies House number and SIC, delivered once. The price is the same in the app, the API and MCP. There are no seats, no telephone surcharge and no separate export or API credits.

ActionCreditsPerStatus
Count, breakdown, preview, machine quote, catalogue, title expansion0callconfirmed
Full UK contact record delivered, any channel or field set1recordconfirmed
Company-only record (no named contact)0.1recordproposed
Contact enrichment, match found (0 if already licensed)1matchconfirmed
Company lookup, no contact details0callto confirm
Outright ownership1.8recordproposed

Never charged: a failed lookup, a duplicate, a suppressed record, a record you already hold, a re-download of a record still under licence, and a verification re-check. Credits are whole numbers on every charge in the current build. The fractional rates are proposed and not yet in force.

The prices, ex VAT, are below (price model A, from 13 October 2026).

  • One credit buys one record at the per-contact scale: 25p a record under 10,000, 22p from 10,000, 19.5p from 25,000 and 17p from 50,000. The size of a purchase picks one band for all of it, and there is no minimum order.
  • A 40,000 credit pack is £1,249, and credit pack credits never expire. It is cheaper than the scale from 4,997 records.
  • New customers can subscribe at £500 a month on a 12-month contract for 2,000 records a month, used or lost each month.
  • Pay as you go (£299 a month) and the 12-month plan (£249 a month) stay for existing customers only.
  • The free plan is 100 credits with no card.

A machine quote's gbp_ex_vat is the order bought the cheapest way, and its purchase lists what you need to buy now, cheapest first: the credits your balance does not cover, at the scale or with credit packs.

Credits and credit packs are not refundable once bought, except where the law requires, and no plan has a pro rata refund. Existing customers keep what their signed agreement says until it renews. GET /v1/plans returns all of it as data.

Create an order

POST /v1/orders spends credits against a live quote_id. It needs an Idempotency-Key header and a confirmation, which Spending safely explains. Without a quote_id the answer is 422 quote-required and nothing is charged.

An account made by self-serve sign-up confirms its business name and that it is a UK business before its first order or enrichment, free or paid. Until a person who owns it does, in the app's Settings or with PATCH /v1/account, the answer is 403 business-details-required and nothing is charged.

{ "quote_id": "qte_01JB4M2R6T1Y5W8ZAK8Q2V7XN3", "name": "Leeds marketing Q4", "delivery": ["api", "csv"] }

The order answers 202 with the charge already made.

MemberMeaning
statusqueued, building, verifying, ready, failed or cancelled
credits_charged, credits_remaining, cost_gbpWhat the order cost, the balance right after it and the GBP charge ex VAT
licence_expires_at, licenceWhen the licence ends and its terms
confirmed_byWho approved the spend and from which client: the method, the key id, the OAuth client, the User-Agent and any client certificate fingerprint
records_url, receipt_urlWhere to fetch the records and the signed receipt
validation_report, buyer_kitPresent once ready. See Compliance receipts

Every order records its caller in the audit trail and on invoices. A failed order is refunded in full and fires order.failed.

Wait for the order

An order moves from queued to building, verifying and ready. Subscribe to the order.ready webhook, or poll GET /v1/orders/{id} or get_order. Records, downloads and the receipt answer 409 order-not-ready until the order is ready.

You can cancel while it is queued with POST /v1/orders/{id}/cancel. The credits come back in full, to the buckets they came from. Any later status answers 409 order-not-cancellable, and records already delivered stay under licence.

Fetch the records

GET /v1/orders/{id}/records returns pages of delivered records as JSON or CSV, with the licence block on every page. The default limit is 50 and the maximum 500. A page stops at about 8,000 tokens, so it can hold fewer rows than limit, and it always carries a next_cursor when more remain.

  • Pages. Follow next_cursor until has_more is false. Over MCP, fetch_order_records holds at most 100 rows a page.
  • Columns. fields narrows a CSV to columns of the order's field set.
  • Telephone screening. A number's TPS and CTPS status is as of the screen date shown: tps_ctps_status is the result of the screen on tps_ctps_screened_at, valid until tps_ctps_valid_until, 28 days later. A clear number reads not_screened, with no dates, once that screen is more than 28 days before the day the file is made; a registered number stays registered. Screen the numbers you are supplied yourself before calling, and again every 28 days.
  • Download. GET /v1/orders/{id}/download redirects (302) to a single-use signed URL for the CSV. It lives 5 minutes and is bound to the account.
  • Cost. Fetching again under licence costs 0 credits. Records and the download stop after the licence ends, with the date in the problem, and the receipt stays readable.

A record objected to after delivery stays in the page, so counts and cursors still line up, but its email, telephone number and name are blank and compliance.suppression_status says why. See Suppressions and objections.

Licence

Every self-serve delivery is a 12 month multi-use licence, multi_use_12m.

TermValue
Permitted channelsemail, telephone and post
ReuseUntil the order date plus 12 months. You can push to a CRM, re-download or refresh free until then
ResaleProhibited on standard terms
At expiryRecords stay in your systems, the CRM property flags them, refreshes stop, and ordering again costs 1 credit
TermsData Licence and Sharing Agreement, accepted by click at checkout

Warranty

The policy in force today replaces records when hard bounces exceed 10 percent of an order. Quotes show it as replace_over_threshold_hard_bounce, with the threshold each was issued under in threshold_percent. GET /v1/plans states the current threshold.

Enrich one contact

POST /v1/contacts/enrich returns the full record for one known person, by email or by name and company. It charges 1 credit only on a confident match, and 0 when you already hold the record or nothing matches. It spends, so it follows the same rules as an order: an Idempotency-Key, and a person's confirmation or an agent key that lists enrich_contact.

Test mode

An mdh_test_ key never charges. Its quote shows the price a live order would cost, and its order shows credits_charged 0 and leaves your live balance untouched.

Test orders are visible only to test keys and announce no webhooks. A quote settles once, in one mode: a live key cannot order a quote that a test order used. A test key needs no balance, so an account with no credits can test its integration.

Next steps

  • Understand confirmation in Spending safely.
  • Prove the list is lawful with Compliance receipts.
  • Push records onward: POST /v1/orders/{id}/pushes runs as a dry run unless you set dry_run to false, and a live push needs approval like a spend.