Queries are in the sections below; actions are under Actions. The full list of types and fields is in the schema reference, and there are recipes for the most common cases. To learn what happens without polling, see the webhooks.
Authentication
Keys are generated in Reval → Integrations in your Shopify admin. Name each key after the tool that will use it (“Triple Whale”, “Looker”) and save it right away: it is shown in full exactly once. Afterwards the list only shows its prefix. Send the key on every request as a Bearer token:Authorization, the X-Reval-Api-Key header is equivalent.
- A revoked key stops working immediately. Requests get
401with codeUNAUTHENTICATED. - Reval stores only a hash of the key. If you lose it, revoke it and generate another.
- You can have up to 25 active keys per store, each with a name of up to 60 characters. The list shows each key’s last use, so you know which ones to revoke.
- When you generate a key you choose read and write or read-only. A read-only key queries everything but cannot run actions (see Actions). The type cannot be changed later: revoke and generate another.
First query
- Only
POSTwith a JSON body{ "query", "variables", "operationName" }is accepted: one operation per request, no batching and noGET. - The endpoint answers CORS, so a browser tool can call it. Do not do that from your storefront: the key would be exposed to anyone who opens the page source.
What you can query
Objects that exist in Shopify carry their Shopify GID so you can join them against the Admin API:
shopifyOrderId, shopifyCustomerId, shopifyVariantId, shopifyProductId. Mercado Pago identifiers (mercadoPagoPreapprovalId, mercadoPagoPaymentId) let you reconcile against your MP account; credentials are never exposed.
Conventions
- Amounts (
Money) are strings with two decimals:"18500.00". The currency is thecurrencyfield on the same object. - Dates (
DateTime) are ISO-8601 in UTC:"2026-11-02T13:00:00.000Z". - Enums are upper-case:
ACTIVE,PAUSED,CANCELLED,MONTHS,PERCENT,DYNAMIC_BOX. - Reval ids are opaque; always use the one the API returned.
Pagination
Every list is a Shopify-style connection: ask forfirst items and continue with after using the previous page’s endCursor.
nodesis the shortcut when you do not need each row’s cursor.totalCountcounts every row matching the filter, not just the page.reverse: trueflips the order (oldest first).- Nested lists (
subscription.orders,customer.subscriptions) paginate the same way.
Filters
Each list takes afilter with the most used fields:
Limits
Limits exist so a heavy integrator can never affect the checkout or the charges. When a query crosses one, the response says which:
Depth counts model objects:
subscriptions › items › plan › group is four levels. edges, node, nodes and pageInfo do not count.
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset (epoch seconds) so your client can pace itself.
Errors
Errors follow the GraphQL format, with anextensions.code your code can switch on:
Business rules of the actions (invalid state, minimum commitment, archived plan, a Mercado Pago refusal) are not errors: they come back in
userErrors with 200. See Actions.
Actions
Beyond reading, the API lets you act on your store’s subscriptions with the same actions the merchant has in the admin: pause, resume, cancel, skip the next delivery, change products and quantities, update the address and generate a portal link. It also lets you build checkout links with several products and the customer’s details already filled in, so a bot can close the sale with a ready link. They are GraphQL mutations on the same endpoint. Every action has exactly the admin’s effects: Mercado Pago is updated first (if it refuses, nothing changes in Reval), price and shipping are recomputed when they change, the same events fire to Klaviyo, Flow and your webhooks, and the subscription’s timeline names “API (key name)” as the author.Read-only keys
When you generate a key in Reval → Integrations you choose read and write or read-only. A read-only key can run any query, but every mutation answers403 with the code FORBIDDEN_READ_ONLY. Use it for dashboards and reports; keep read-write keys for the automations that actually act.
Idempotency
Actions move real charges and shipments, so a retry (a timeout, a crashed worker) must not repeat them. Send anIdempotency-Key header with a unique identifier per operation (a UUID). If the same key arrives again with the same body within 24 hours, the API returns the original answer without running anything and sets the header Idempotency-Replayed: true. If it arrives with a different body, it answers 422 with IDEMPOTENCY_KEY_REUSED: that is a bug on your side, not a second operation.
Business rejections: userErrors
A mutation never fails with a GraphQL error for a business rule. It answers 200 with a payload carrying the object or a userErrors list with a code your code can switch on, and the subscription stays as it was:
Available mutations
All return
{ subscription, userErrors }, except subscriptionPortalLink and checkoutLinkCreate, which return { url, expiresAt, userErrors }.
Pause from a support bot