EmailmoversMyDataHub docs
Browse the docs

Reference / REST reference

Reference

List credit purchases

GET /v1/account/purchases. Credits bought by card, newest first, each with its price excluding VAT, the VAT, the total and, once paid, its payment receipt.

Generated from the contractsView as Markdown

GET /v1/account/purchases

Credits bought by card, newest first, each with its price excluding VAT, the VAT, the total and, once paid, its payment receipt. payments says whether card payments are switched on here and whether they are Stripe test mode.

PropertyValue
EndpointGET https://mydatahub.emailmovers.com/v1/account/purchases
Operation idlistCreditPurchases
CostFree (0 credits)
AccessAn API key or an OAuth 2.1 token with the scope account:read.
TagAccount

Request

Parameters

NameInTypeRequiredDescription
limitqueryinteger (1 to 100)noItems per page, 1 to 100. Default 25.
cursorquerystringnoAn opaque cursor from next_cursor. Pass it back unchanged.
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/account/purchases" \
  -H "Authorization: Bearer $MYDATAHUB_API_KEY"

Responses

200: A page of credit purchases.

Headers: RateLimit, RateLimit-Policy.

MemberTypeAlways presentDescription
dataarray of CreditPurchaseyes
data[].idstringyesFormat: a credit purchase id: pur_ followed by a 26 character ULID in upper case Crockford base32, such as pur_01JB4R7K2V7XN3M9R6T1Y5W8ZA.
data[].statusenum: pending, paid, expiredyespending until Stripe says the payment is paid; paid once the credits are in the balance; expired when the checkout closed unpaid (nothing was taken).
data[].labelstringyesWhat is bought, in words, numbers first.
data[].linesarray of CreditPurchaseLineyes
data[].creditsinteger (0 or more)yesCredits the purchase adds when paid.
data[].gbp_ex_vatnumber (0 or more)yesPounds sterling excluding VAT, to two decimal places.
data[].vat_rate_percentnumber (0 to 100)yes
data[].vat_gbpnumber (0 or more)yesPounds sterling, to two decimal places.
data[].total_gbpnumber (0 or more)yesWhat the card is charged, VAT included.
data[].currencyGBPyes
data[].gbp_per_creditnumber (0 or more)yesWhat one credit of this purchase cost, excluding VAT, to six decimal places. Orders value the credits they spend at it.
data[].credits_addedinteger (0 or more)yes0 until the payment is paid.
data[].checkout_urlstring (uri) or nullyesStripe Checkout, while the purchase is pending; null once paid or expired.
data[].test_modebooleanyesMade with a Stripe test key: test cards only, and no money moves.
data[].created_atstring (date-time)yes
data[].expires_atstring (date-time) or nullyesWhen the checkout closes if it is not paid.
data[].paid_atstring (date-time) or nullyes
data[].attentionPurchaseAttention or nullyes
data[].receiptPaymentReceipt or nullyesOnce paid. The buyer's name, billing address and VAT number are shown only to a signed-in person with admin; anyone else sees them as null.
has_morebooleanyesWhether another page follows.
next_cursorstring or nullyesPass as cursor to fetch the next page; null on the last page.
paymentsobjectyesHow credits are bought here.
payments.availablebooleanyesWhether card payments are switched on for this server.
payments.test_modebooleanyesStripe test mode: test cards only.
payments.vat_rate_percentnumber (0 to 100)yes

Example response

{
  "data": [
    {
      "id": "pur_01JB4R7K2V7XN3M9R6T1Y5W8ZA",
      "label": "1 credit pack of 40,000",
      "lines": [
        {
          "id": "credit_pack_40000",
          "quantity": 1,
          "credits": 40000,
          "gbp_ex_vat": 1249
        }
      ],
      "credits": 40000,
      "gbp_ex_vat": 1249,
      "vat_rate_percent": 20,
      "vat_gbp": 249.8,
      "total_gbp": 1498.8,
      "currency": "GBP",
      "gbp_per_credit": 0.031225,
      "test_mode": true,
      "created_at": "2026-10-16T10:00:00Z",
      "expires_at": "2026-10-17T10:00:00Z",
      "attention": null,
      "status": "paid",
      "credits_added": 40000,
      "checkout_url": null,
      "paid_at": "2026-10-16T10:03:12Z",
      "receipt": {
        "number": "MDH-000042",
        "issued_at": "2026-10-16T10:03:12Z",
        "supplier": {
          "name": "Example Supplier Limited",
          "company_number": "00000000",
          "registered_office": "1 Example Street, Exampletown, EX1 1EX, England",
          "vat_number": "GB000000000"
        },
        "customer": {
          "organisation_id": "org_01JA0Q2V7XN3M9R6T1Y5W8ZAK8",
          "organisation_name": "Example Agency Ltd",
          "business_name": "Example Agency Ltd",
          "name": "Example Agency Ltd",
          "address": {
            "line1": "2 Sample Road",
            "line2": null,
            "city": "Exampletown",
            "postal_code": "EX2 2EX",
            "state": null,
            "country": "GB"
          },
          "vat_number": "GB999999999"
        },
        "description": "1 credit pack of 40,000",
        "credits": 40000,
        "gbp_per_credit": 0.031225,
        "gbp_ex_vat": 1249,
        "vat_rate_percent": 20,
        "vat_gbp": 249.8,
        "total_gbp": 1498.8,
        "paid_by": "card",
        "payment_reference": "pi_test_EXAMPLE",
        "refunds": "Credits and credit packs are not refundable once bought, except where the law requires.",
        "test_mode": true
      }
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "payments": {
    "available": true,
    "test_mode": true,
    "vat_rate_percent": 20
  }
}

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).
403insufficient-scope, confirmation-required, business-details-required, licence-acceptance-required, dpa-acceptance-required, agent-budget-exceededThe token lacks a scope (insufficient-scope, with required_scope and a WWW-Authenticate step-up challenge); no person confirmed the spend and no agent key covers it (confirmation-required, with an approval_url); an agent key's per-order cap or monthly budget does not cover it (agent-budget-exceeded); an account made by self-serve sign-up has not yet confirmed its business name and that it is a UK business, which its first order needs (business-details-required); the order needs the Data Licence and Sharing Agreement accepted at the version in force (licence-acceptance-required); or a suppression upload comes before the organisation has accepted the Article 28 data processing agreement in force (dpa-acceptance-required). Nothing is charged.
422validation-failed, quote-required, dataset-unavailableThe request is not valid. errors lists every problem with a JSON pointer and did_you_mean.
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.