# Get plans and prices

> GET /v1/plans. Plans, credit packs, credit rules, licence terms, the guarantee and the free trial, in GBP excluding VAT.

Source: https://emailmovers.com/mydatahub/docs/reference/rest/get-plans

`GET /v1/plans`

Plans, credit packs, credit rules, licence terms, the guarantee and the free trial, in GBP excluding VAT. The same content as https://mydatahub.emailmovers.com/pricing.json. One credit buys one complete UK record at the same price in the app, API and MCP server.

| Property | Value |
| --- | --- |
| Endpoint | `GET https://mydatahub.emailmovers.com/v1/plans` |
| Operation id | `getPlans` |
| Cost | Free (0 credits) |
| Access | No account, key or token needed. |
| MCP tool | [`get_plans`](https://emailmovers.com/mydatahub/docs/reference/mcp/get_plans.md) |
| Tag | Catalogue |

> **Not yet live.** MyDataHub v2 is built and tested locally and is not yet live. The v2 hosts open at launch, date to confirm. This page describes the contract the API is tested against.

## Request

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `MyDataHub-Version` | header | string | no | The 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

```bash
curl "https://mydatahub.emailmovers.com/v1/plans"
```

## Responses

### 200: Plans and prices.

Headers: `RateLimit`, `RateLimit-Policy`.

| Member | Type | Always present | Description |
| --- | --- | --- | --- |
| `version` | string | yes |  |
| `valid_from` | string (date) | yes |  |
| `currency` | `GBP` | yes |  |
| `vat_treatment` | string | yes |  |
| `credit_definition` | string | yes |  |
| `price_scale` | `PriceScale` | yes | The per-contact scale: 1 credit buys 1 record at the rate of the band the purchase falls in. A quote's purchase options compare it with the credit pack and lead with the cheapest. |
| `price_scale.id` | `per_contact_scale` | yes |  |
| `price_scale.name` | string | yes |  |
| `price_scale.status` | enum: `confirmed`, `proposed`, `to_confirm` | yes | confirmed is in force; proposed awaits a decision; to_confirm is a figure still being checked. |
| `price_scale.available_to` | enum: `everyone`, `new_customers`, `existing_customers` | yes | everyone; new_customers only (the subscription); existing_customers only, who keep their prices (pay as you go and the 12-month plan). |
| `price_scale.minimum_order_records` | integer (0 or more) | yes |  |
| `price_scale.rule` | string | yes | How a purchase is priced, in words. |
| `price_scale.bands` | array of `PriceBand` | yes |  |
| `plans` | array of `Plan` | yes |  |
| `plans[].id` | string | yes | Such as free, pay_as_you_go or plan_12_month. |
| `plans[].name` | string | yes |  |
| `plans[].kind` | enum: `free`, `subscription`, `pack` | yes |  |
| `plans[].status` | enum: `confirmed`, `proposed`, `to_confirm` | yes | confirmed is in force; proposed awaits a decision; to_confirm is a figure still being checked. |
| `plans[].available_to` | enum: `everyone`, `new_customers`, `existing_customers` | yes | everyone; new_customers only (the subscription); existing_customers only, who keep their prices (pay as you go and the 12-month plan). |
| `plans[].price_gbp_ex_vat` | number (0 or more) | yes | Pounds sterling excluding VAT, to two decimal places. |
| `plans[].billing_period` | enum: `once`, `month`, `year` | yes |  |
| `plans[].contract_months` | integer (0 or more) or null | no | The contract's length in months, such as 12; absent when there is none. |
| `plans[].annual_price_gbp_ex_vat` | number (0 or more) or null | no |  |
| `plans[].credits` | integer (0 or more) | yes | Credits per billing period, or once. |
| `plans[].per_record_gbp` | number (0 or more) or null | yes | Price per record at full use of the allowance; null for the free plan. |
| `plans[].rollover_cap_credits` | integer (0 or more) or null | no | Subscription credits roll over while subscribed, up to this many; 0 when each period's credits are used or lost. |
| `plans[].credits_expire` | boolean | yes |  |
| `plans[].for_whom` | string | yes |  |
| `plans[].notes` | string | no |  |
| `credit_packs` | array of `CreditPack` | yes |  |
| `credit_packs[].id` | string | yes | Such as free, pay_as_you_go or plan_12_month. |
| `credit_packs[].name` | string | yes |  |
| `credit_packs[].kind` | `pack` | yes |  |
| `credit_packs[].status` | enum: `confirmed`, `proposed`, `to_confirm` | yes | confirmed is in force; proposed awaits a decision; to_confirm is a figure still being checked. |
| `credit_packs[].available_to` | enum: `everyone`, `new_customers`, `existing_customers` | yes | everyone; new_customers only (the subscription); existing_customers only, who keep their prices (pay as you go and the 12-month plan). |
| `credit_packs[].price_gbp_ex_vat` | number (0 or more) | yes | Pounds sterling excluding VAT, to two decimal places. |
| `credit_packs[].billing_period` | `once` | yes |  |
| `credit_packs[].contract_months` | integer (0 or more) or null | no | The contract's length in months, such as 12; absent when there is none. |
| `credit_packs[].annual_price_gbp_ex_vat` | number (0 or more) or null | no |  |
| `credit_packs[].credits` | integer (0 or more) | yes | Credits per billing period, or once. |
| `credit_packs[].per_record_gbp` | number (0 or more) or null | yes | Price per record at full use of the allowance; null for the free plan. |
| `credit_packs[].rollover_cap_credits` | integer (0 or more) or null | no | Subscription credits roll over while subscribed, up to this many; 0 when each period's credits are used or lost. |
| `credit_packs[].credits_expire` | boolean | yes |  |
| `credit_packs[].for_whom` | string | yes |  |
| `credit_packs[].notes` | string | no |  |
| `credit_rules` | array of `CreditRule` | yes |  |
| `credit_rules[].action` | string | yes |  |
| `credit_rules[].label` | string | yes |  |
| `credit_rules[].credits` | number (0 or more) | yes | Credits, to one decimal place: whole at 1 credit a record, fractional only where a rule is (0.1 company-only, 1.8 outright, both proposed). |
| `credit_rules[].unit` | enum: `call`, `record`, `match` | yes |  |
| `credit_rules[].status` | enum: `confirmed`, `proposed`, `to_confirm` | yes | confirmed is in force; proposed awaits a decision; to_confirm is a figure still being checked. |
| `credit_rules[].note` | string | no |  |
| `licence` | array of `LicenceTerms` | yes |  |
| `licence[].licence_type` | enum: `multi_use_12m`, `outright` | yes | multi_use_12m (12 month multi-use, every plan) or outright (1.8 credits a record, proposed). |
| `licence[].status` | enum: `confirmed`, `proposed` | yes |  |
| `licence[].credits_per_record` | number | yes |  |
| `licence[].permitted_channels` | array of enum: `email`, `telephone`, `post` | yes |  |
| `licence[].reuse_months` | integer or null | yes | 12 for multi_use_12m; null for outright. |
| `licence[].resale_prohibited` | boolean | yes |  |
| `licence[].warranty_url` | string (uri) | yes |  |
| `licence[].terms_version` | string | yes |  |
| `guarantee` | object | yes |  |
| `guarantee.current` | `Warranty` | yes | The bounce warranty that covers delivered records, with the threshold it was issued under. |
| `guarantee.proposed` | `Warranty` or null | yes |  |
| `guarantee.refunds` | array of string | yes |  |
| `trial` | object | yes |  |
| `trial.credits` | integer (0 or more) | yes |  |
| `trial.card_required` | boolean | yes |  |
| `trial.expires` | boolean | yes |  |
| `promises` | array of `PricingPromise` | yes |  |
| `promises[].key` | string | yes |  |
| `promises[].statement` | string | yes |  |
| `promises[].in_practice` | string | yes |  |
| `meters` | array of `Meter` | yes | What agents and code are metered on, in credits, the same on every surface. |
| `meters[].action` | string | yes | What is metered, such as record or enrich_contact. |
| `meters[].unit` | enum: `record`, `match`, `call` | yes |  |
| `meters[].credits` | number (0 or more) | yes | Credits per unit. |
| `meters[].status` | enum: `confirmed`, `proposed`, `to_confirm` | yes | confirmed is in force; proposed awaits a decision; to_confirm is a figure still being checked. |
| `action_path` | array of `ActionPathStep` | yes | How to buy: quote_order for a machine quote, create_order with a confirmation, and the top-up page when the balance is short. |
| `action_path[].step` | integer (1 or more) | yes |  |

Showing the first 80 of 83 members. The OpenAPI document and the MCP tool list hold the full schema.

#### Example response

```json
{
  "version": "2026-10",
  "valid_from": "2026-10-13",
  "currency": "GBP",
  "vat_treatment": "Prices exclude VAT at 20 percent.",
  "credit_definition": "1 credit buys 1 complete UK record, delivered once, at the per-contact scale's rate, the same in the app, API and MCP server.",
  "price_scale": {
    "id": "per_contact_scale",
    "name": "Per-contact scale",
    "status": "confirmed",
    "available_to": "everyone",
    "minimum_order_records": 0,
    "rule": "The credits bought, after any balance, pick one band, and every credit in the purchase is at its rate. A quote compares the scale with the credit pack and leads with the cheaper.",
    "bands": [
      {
        "from_records": 1,
        "to_records": 2999,
        "gbp_per_record": 0.25
      },
      {
        "from_records": 3000,
        "to_records": 9999,
        "gbp_per_record": 0.25
      },
      {
        "from_records": 10000,
        "to_records": 24999,
        "gbp_per_record": 0.22
      },
      {
        "from_records": 25000,
        "to_records": 49999,
        "gbp_per_record": 0.195
      },
      {
        "from_records": 50000,
        "to_records": null,
        "gbp_per_record": 0.17
      }
    ]
  },
  "plans": [
    {
      "id": "free",
      "name": "Free",
      "kind": "free",
      "status": "confirmed",
      "available_to": "everyone",
      "price_gbp_ex_vat": 0,
      "billing_period": "once",
      "credits": 100,
      "per_record_gbp": null,
      "credits_expire": false,
      "for_whom": "Triallists, human or agent",
      "notes": "No card"
    },
    {
      "id": "pay_as_you_go",
      "name": "Pay as you go",
      "kind": "subscription",
      "status": "confirmed",
      "available_to": "existing_customers",
      "price_gbp_ex_vat": 299,
      "billing_period": "month",
      "credits": 1000,
      "per_record_gbp": 0.299,
      "rollover_cap_credits": 12000,
      "credits_expire": false,
      "for_whom": "Existing customers, who keep this price",
      "notes": "Cancel any time. Not sold to new customers since 13 October 2026."
    },
    {
      "id": "plan_12_month",
      "name": "12-month plan",
      "kind": "subscription",
      "status": "confirmed",
      "available_to": "existing_customers",
      "price_gbp_ex_vat": 249,
      "billing_period": "month",
      "annual_price_gbp_ex_vat": 2988,
      "credits": 1000,
      "per_record_gbp": 0.249,
      "rollover_cap_credits": 12000,
      "credits_expire": false,
      "for_whom": "Existing customers, who keep this price",
      "notes": "Not sold to new customers since 13 October 2026."
    },
    {
      "id": "subscription_2000",
      "name": "Subscription",
      "kind": "subscription",
      "status": "confirmed",
      "available_to": "new_customers",
      "price_gbp_ex_vat": 500,
      "billing_period": "month",
      "contract_months": 12,
      "annual_price_gbp_ex_vat": 6000,
      "credits": 2000,
      "per_record_gbp": 0.25,
      "rollover_cap_credits": 0,
      "credits_expire": true,
      "for_whom": "Teams that buy every month",
      "notes": "A 12-month contract. Each month's 2,000 records are used or lost; records beyond them cost the quote's cheapest purchase."
    }
  ],
  "credit_packs": [
    {
      "id": "credit_pack_40000",
      "name": "Credit pack 40,000",
      "kind": "pack",
      "status": "confirmed",
      "available_to": "everyone",
      "price_gbp_ex_vat": 1249,
      "billing_period": "once",
      "credits": 40000,
      "per_record_gbp": 0.031,
      "credits_expire": false,
      "for_whom": "Anyone buying about 5,000 records or more"
    }
  ],
  "credit_rules": [
    {
      "action": "count",
      "label": "Count, breakdown, preview, machine quote, catalogue, title expansion",
      "credits": 0,
      "unit": "call",
      "status": "confirmed"
    },
    {
      "action": "record",
      "label": "Full UK contact record delivered, any channel or field set",
      "credits": 1,
      "unit": "record",
      "status": "confirmed"
    },
    {
      "action": "company_only_record",
      "label": "Company-only record (no named contact)",
      "credits": 0.1,
      "unit": "record",
      "status": "proposed"
    },
    {
      "action": "enrich_contact",
      "label": "Contact enrichment, match found",
      "credits": 1,
      "unit": "match",
      "status": "confirmed",
      "note": "0 if already licensed"
    },
    {
      "action": "lookup_company",
      "label": "Company lookup, no contact details",
      "credits": 0,
      "unit": "call",
      "status": "to_confirm"
    },
    {
      "action": "outright",
      "label": "Outright ownership",
      "credits": 1.8,
      "unit": "record",
      "status": "proposed"
    }
  ],
  "licence": [
    {
      "licence_type": "multi_use_12m",
      "status": "confirmed",
      "credits_per_record": 1,
      "permitted_channels": ["email", "telephone", "post"],
      "reuse_months": 12,
      "resale_prohibited": true,
      "warranty_url": "https://emailmovers.com/trust/warranty",
      "terms_version": "2026-09"
    }
  ],
  "guarantee": {
    "current": {
      "policy": "replace_over_threshold_hard_bounce",
      "threshold_percent": 10,
      "url": "https://emailmovers.com/trust/warranty"
    },
    "proposed": {
      "policy": "replace_any_hard_bounce_30d",
      "url": "https://emailmovers.com/trust/warranty"
    },
    "refunds": [
      "Credits and credit packs are not refundable once bought, except where the law requires.",
      "Existing customers keep what their signed agreement says until it renews."
    ]
  },
  "trial": {
    "credits": 100,
    "card_required": false,
    "expires": false
  },
  "meters": [
    {
      "action": "record",
      "unit": "record",
      "credits": 1,
      "status": "confirmed"
    },
    {
      "action": "enrich_contact",
      "unit": "match",
      "credits": 1,
      "status": "confirmed"
    },
    {
      "action": "company_only_record",
      "unit": "record",
      "credits": 0.1,
      "status": "proposed"
    },
    {
      "action": "outright",
      "unit": "record",
      "credits": 1.8,
      "status": "proposed"
    },
    {
      "action": "count",
      "unit": "call",
      "credits": 0,
      "status": "confirmed"
    }
  ],
  "action_path": [
    {
      "step": 1,
      "action": "quote_order",
      "rest": "POST /v1/quotes",
      "description": "Get a signed machine quote for a count, valid 24 hours. Free."
    },
    {
      "step": 2,
      "action": "create_order",
      "rest": "POST /v1/orders",
      "description": "Spend credits against the quote_id with a person's confirmation or an agent key within its limits."
    },
    {
      "step": 3,
      "action": "https://mydatahub.emailmovers.com/billing/top-up",
      "rest": null,
      "description": "When the balance is short, buy one of the quote's purchase options (the cheapest comes first) through Stripe Checkout, then retry step 2."
    }
  ],
  "promises": [
    {
      "key": "looking_is_free",
      "statement": "Looking is free forever",
      "in_practice": "Filters, counts, breakdowns, masked previews, machine quotes, plans and trust documents need no account or card."
    },
    {
      "key": "never_pay_twice",
      "statement": "Never pay twice",
      "in_practice": "Re-downloads under licence, duplicates, suppressed records, records you already hold and failed lookups cost 0."
    }
  ]
}
```

## 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](https://emailmovers.com/mydatahub/docs/rate-limits.md).

| Status | Problem codes | When |
| --- | --- | --- |
| 400 | [`invalid-request`](https://emailmovers.com/mydatahub/docs/errors/invalid-request.md), [`idempotency-key-required`](https://emailmovers.com/mydatahub/docs/errors/idempotency-key-required.md), [`unsupported-version`](https://emailmovers.com/mydatahub/docs/errors/unsupported-version.md) | The request could not be read, or an Idempotency-Key is missing. |
| 429 | [`rate-limited`](https://emailmovers.com/mydatahub/docs/errors/rate-limited.md) | Too many requests. Wait for Retry-After. |
| Any other failure | [`internal-error`](https://emailmovers.com/mydatahub/docs/errors/internal-error.md), [`service-unavailable`](https://emailmovers.com/mydatahub/docs/errors/service-unavailable.md), [`tps-screen-expired`](https://emailmovers.com/mydatahub/docs/errors/tps-screen-expired.md) | Something 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. |
