EmailmoversMyDataHub docs
Browse the docs

Reference / REST reference

Reference

Get a quote

GET /v1/quotes/{id}. A machine quote (kind machine, 24 hours) or a human sales quote (kind sales, 14 days).

Generated from the contractsView as Markdown

GET /v1/quotes/{id}

A machine quote (kind machine, 24 hours) or a human sales quote (kind sales, 14 days). An agent in the same organisation can settle another agent's machine quote after checking its signature, dataset version and expiry; outside the organisation, re-quote.

PropertyValue
EndpointGET https://mydatahub.emailmovers.com/v1/quotes/{id}
Operation idgetQuote
CostFree (0 credits)
AccessNo account needed. An API key or OAuth token with the scope quotes:read is optional and adds your organisation's own figures.
TagQuotes

Request

Parameters

NameInTypeRequiredDescription
idpathstringyesFormat: a quote id: qte_ followed by a 26 character ULID in upper case Crockford base32, such as qte_01JB4M2R6T1Y5W8ZAK8Q2V7XN3.
MyDataHub-VersionheaderstringnoThe dated API version, pinned per key when left out. Non-breaking changes ship as new dates; the path major changes only for breaking changes, with a 12 month deprecation window.

Example request

curl "https://mydatahub.emailmovers.com/v1/quotes/qte_01JB4P2V7XN3M9R6T1Y5W8ZAK8"

Responses

200: The quote.

Headers: RateLimit, RateLimit-Policy.

MachineQuote

MemberTypeAlways presentDescription
idstringyesFormat: a quote id: qte_ followed by a 26 character ULID in upper case Crockford base32, such as qte_01JB4M2R6T1Y5W8ZAK8Q2V7XN3.
kindmachineyes
organisation_idstring or nullyesThe organisation the quote belongs to; create_order settles it only there. null for a quote made without an account, which the first organisation to confirm it takes.
count_idstringyesThe count the quote was priced from.
datasetenum: uk_contacts, ie_contacts, global_contactsnoThe dataset an audience draws from. uk_contacts is live; ie_contacts and global_contacts are listed but not yet served.
dataset_versionstringyesThe immutable weekly build a count is bound to, such as 2026-W39. The last 52 stay queryable.
field_setstringno
recordsinteger (0 or more)yesRecords after overlap and suppression; what you would receive.
removedobjectyesRecords left out and never charged.
removed.already_heldinteger (0 or more)yes
removed.suppressedinteger (0 or more)yes
credits_per_recordnumber (0 or more)yes1 for a complete UK record; 1.8 outright (proposed).
credits_requirednumber (0 or more)yesrecords times credits_per_record (creditsFor).
credits_availablenumber (0 or more) or nullyesYour balance; null when signed out.
balance_afternumber or nullyescredits_available less credits_required; negative means a top-up is needed; null when signed out.
gbp_ex_vatnumber (0 or more)yesWhat credits_required cost bought the cheapest way, at the per-contact scale or with credit packs, excluding VAT. The same for every caller; purchase says what this caller needs to buy.
purchasePurchaseyesHow to buy the credits the order needs, worked out by one function (cheapestPurchase) everywhere a price is shown. The caller's own, like the balance: read fresh on every read of the quote.
purchase.credits_to_buyinteger (0 or more)yescredits_required less the balance: all of it when signed out, 0 when the balance covers the order.
purchase.cheapeststring or nullyesThe id of the cheapest option; null when nothing needs buying.
purchase.gbp_ex_vatnumber (0 or more)yesWhat the cheapest option costs, excluding VAT; 0 when nothing needs buying.
purchase.optionsarray of PurchaseOptionyesCheapest first: the per-contact scale, and the credit pack (with any rest at the scale) when it is on sale. At the same price, the option that buys more credits comes first.
licenceLicenceyesLicence terms as data, on every quote, order, records page and receipt. Records stay usable, pushable and re-downloadable free until reuse_until.
licence.typeenum: multi_use_12m, outrightyesmulti_use_12m (12 month multi-use, every plan) or outright (1.8 credits a record, proposed).
licence.reuse_untilstring (date) or nullyesOrder date plus 12 months; null for outright.
licence.resale_prohibitedbooleanyes
licence.permitted_channelsarray of enum: email, telephone, postyesemail, telephone and post on standard terms.
licence.warranty_urlstring (uri)yes
licence.terms_versionstringyesThe version of the Data Licence and Sharing Agreement the licence is under, such as 1.0.
licence.terms_urlstring (uri)noWhere that version of the Data Licence and Sharing Agreement is published.
warrantyWarrantyyesThe bounce warranty that covers delivered records, with the threshold it was issued under.
warranty.policyenum: replace_over_threshold_hard_bounce, replace_any_hard_bounce_30dyesreplace_over_threshold_hard_bounce is the current policy: records are replaced when hard bounces exceed threshold_percent of an order. replace_any_hard_bounce_30d is proposed and not yet in force. The current policy's id replaced one that named the threshold, a change to this public enum made before v2 went live.
warranty.threshold_percentnumber (0 to 100)noreplace_over_threshold_hard_bounce only, and required there: the share of an order, in percent, that hard bounces must exceed before records are replaced. It is the threshold the document was issued under.
warranty.urlstring (uri)yes
created_atstring (date-time)no
expires_atstring (date-time)yes24 hours after creation.
blockersarray of QuoteBlockeryes
blockers[].codeenum: insufficient_credits, account_required, agent_budget_exceeded, dataset_unavailable, count_expiredyes
blockers[].detailstringyes
blockers[].top_up_urlstring (uri)no
signatureQuoteSignatureyesThe signature over the machine quote's price, so an agent can hand the quote to another agent and both can check it. Verify it with the key at jwks_url.
signature.algES256yes
signature.kidstringyesThe signing key id in jwks_url.
signature.jwks_urlstring (uri)yes
signature.jwsstringyesA compact JWS whose payload is the quote's id, organisation_id, count_id, dataset_version, records, credits_required, gbp_ex_vat, licence, expires_at.

SalesQuote

MemberTypeAlways presentDescription
idstringyesFormat: a quote id: qte_ followed by a 26 character ULID in upper case Crockford base32, such as qte_01JB4M2R6T1Y5W8ZAK8Q2V7XN3.
kindsalesyes
statusenum: draft, sent, accepted, paid, expired, withdrawnyes
created_atstring (date-time)yes
valid_untilstring (date)yes14 days after creation.
created_byobjectyes
created_by.roleenum: user, account_manageryes
created_by.namestringyes
customerstringyesThe organisation the quote is for.
count_idstring or nullyes
field_setstringyes
recordsinteger (0 or more)yesRecords the quote covers.
credits_per_recordnumber (0 or more)yesCredits a record under the licence: 1, or 1.8 outright (proposed).
linesarray of SalesQuoteLineyes
lines[].descriptionstringyes
lines[].quantityinteger (0 or more)yes
lines[].unit_price_gbpnumber (0 or more)yesPounds sterling excluding VAT, to two decimal places.
lines[].amount_gbpnumber (0 or more)yesPounds sterling excluding VAT, to two decimal places.
subtotal_gbp_ex_vatnumber (0 or more)yesPounds sterling excluding VAT, to two decimal places.
vat_gbpnumber (0 or more)yesPounds sterling excluding VAT, to two decimal places.
total_gbp_inc_vatnumber (0 or more)yesPounds sterling excluding VAT, to two decimal places.
balance_afternumber or nullyesThe customer's credits after the order. Paying by card or invoice leaves the balance as it is; null when the customer has no account yet.
licenceLicenceyesLicence terms as data, on every quote, order, records page and receipt. Records stay usable, pushable and re-downloadable free until reuse_until.
licence.typeenum: multi_use_12m, outrightyesmulti_use_12m (12 month multi-use, every plan) or outright (1.8 credits a record, proposed).
licence.reuse_untilstring (date) or nullyesOrder date plus 12 months; null for outright.
licence.resale_prohibitedbooleanyes
licence.permitted_channelsarray of enum: email, telephone, postyesemail, telephone and post on standard terms.
licence.warranty_urlstring (uri)yes
licence.terms_versionstringyesThe version of the Data Licence and Sharing Agreement the licence is under, such as 1.0.
licence.terms_urlstring (uri)noWhere that version of the Data Licence and Sharing Agreement is published.
warrantyWarrantyyesThe bounce warranty that covers delivered records, with the threshold it was issued under.
warranty.policyenum: replace_over_threshold_hard_bounce, replace_any_hard_bounce_30dyesreplace_over_threshold_hard_bounce is the current policy: records are replaced when hard bounces exceed threshold_percent of an order. replace_any_hard_bounce_30d is proposed and not yet in force. The current policy's id replaced one that named the threshold, a change to this public enum made before v2 went live.
warranty.threshold_percentnumber (0 to 100)noreplace_over_threshold_hard_bounce only, and required there: the share of an order, in percent, that hard bounces must exceed before records are replaced. It is the threshold the document was issued under.
warranty.urlstring (uri)yes
payment_methodsarray of enum: card, invoiceyes
pay_urlstring (uri)yesPay by card or request an invoice link, no account needed.
pdf_urlstring (uri)yes

Example response

{
  "id": "qte_01JB4P2V7XN3M9R6T1Y5W8ZAK8",
  "kind": "sales",
  "status": "sent",
  "created_at": "2026-09-26T11:00:00Z",
  "valid_until": "2026-10-10",
  "created_by": {
    "role": "account_manager",
    "name": "Jordan Hale"
  },
  "customer": "Example Agency Ltd",
  "count_id": "cnt_7K2PQ4MAXN3R6TBY5WDZ",
  "field_set": "standard",
  "records": 12310,
  "credits_per_record": 1,
  "lines": [
    {
      "description": "12,310 UK records, standard field set, 12-month multi-use licence",
      "quantity": 12310,
      "unit_price_gbp": 0.22,
      "amount_gbp": 2708.2
    }
  ],
  "subtotal_gbp_ex_vat": 2708.2,
  "vat_gbp": 541.64,
  "total_gbp_inc_vat": 3249.84,
  "balance_after": 6200,
  "licence": {
    "type": "multi_use_12m",
    "reuse_until": "2027-09-26",
    "resale_prohibited": true,
    "permitted_channels": ["email", "telephone", "post"],
    "warranty_url": "https://emailmovers.com/trust/warranty",
    "terms_version": "2026-09"
  },
  "warranty": {
    "policy": "replace_over_threshold_hard_bounce",
    "threshold_percent": 10,
    "url": "https://emailmovers.com/trust/warranty"
  },
  "payment_methods": ["card", "invoice"],
  "pay_url": "https://mydatahub.emailmovers.com/quotes/qte_01JB4P2V7XN3M9R6T1Y5W8ZAK8/pay",
  "pdf_url": "https://mydatahub.emailmovers.com/quotes/qte_01JB4P2V7XN3M9R6T1Y5W8ZAK8.pdf"
}

Errors

Every error is a problem object with a code and a next_step. Every response carries the RateLimit and RateLimit-Policy headers; see Rate limits.

StatusProblem codesWhen
400invalid-request, idempotency-key-required, unsupported-versionThe request could not be read, or an Idempotency-Key is missing.
401authentication-required, account-requiredSign in (OAuth) or send an API key (authentication-required), or create a free account for what the anonymous tier does not cover (account-required).
404not-foundNo such object for this organisation.
429rate-limitedToo many requests. Wait for Retry-After.
Any other failureinternal-error, service-unavailable, tps-screen-expiredSomething failed on our side (500 internal-error) or the service is briefly unavailable (503 service-unavailable, with Retry-After). Nothing was charged; retry with the same Idempotency-Key. A count, sample, quote or order with telephone in play is also refused with 503 tps-screen-expired, with no Retry-After, while the dataset version's TPS and CTPS screen is more than 28 days old.