{"openapi":"3.1.0","info":{"title":"Tardis.dev Account API","version":"1.0.0","description":"Manage a Tardis.dev account and find the exchanges and symbols with historical data. Every operation except Authentication is also a tool of the same name on the MCP server at `https://api.tardis.dev/mcp`.\n\n## Terms\n\n- **The user** is the person signed in, or the person who authorized the agent.\n- **Data API**: the historical market data that a Data API key unlocks: the HTTP API, downloadable CSV files, and replay with tardis-machine and the client libraries.\n- **Older subscriptions** have `billingSystem: paddle_classic`, from the billing system Tardis.dev used before. They renew and can be upgraded, but not paid by invoicing or paused.\n\n## Authentication\n\nSend an access token in the `Authorization: Bearer` header. Agents get one through OAuth, as [auth.md](https://api.tardis.dev/auth.md) describes. Scripts and CLIs sign the user in through the browser with `start_sign_in` and `complete_sign_in`, and renew the token with `refresh_sign_in`.\n\n## Permissions\n\nEach member has one role. A website session has every permission of its role; an agent token has only those granted when it was authorized. Each operation's `security` names the permission it needs. Without it, the operation returns `403` with code `601` and `reason`: `role_required` when the role lacks it (`roles` lists the roles that have it), or `permission_missing` when only the token lacks it (authorize the agent again).\n\n| Permission | Roles | Allows |\n| --- | --- | --- |\n| `user:read` | owner, billing, member | Read the current user, their role and sign-in sessions. |\n| `user:write` | owner, billing, member | Change the current user's name and email, and end their sign-in sessions. |\n| `account:read` | owner, billing, member | Read the account and its Data API usage and limits. |\n| `account:write` | owner | Rename the account. |\n| `data_api_keys:read` | owner, member | List Data API keys. |\n| `data_api_keys:write` | owner, member | Create, rotate and revoke Data API keys. |\n| `members:read` | owner | List members and pending invitations. |\n| `members:write` | owner | Invite members, revoke invitations, change roles and remove members. |\n| `billing:read` | owner, billing | Read subscriptions, invoices and billing details. |\n| `billing:write` | owner, billing | Buy, change, cancel, pause and resume subscriptions; send and revise invoices; change billing details; start a trial. |\n\n## Conventions\n\nAmounts are in the `currency` beside them; `total` and fields ending in `Total` include tax.\n\n## Errors\n\nErrors return `AccountError`: a stable `code`, for some codes a `reason`, and a `message` for people. Any operation can return these:\n\n| Status | Code | When |\n| --- | --- | --- |\n| 400 | 110 | The request is invalid; `field` names the wrong field when there is one. |\n| 401 | 600 | The access token is missing, invalid or expired. |\n| 403 | 601 | The role or the token lacks the permission; see Permissions. |\n| 404 | 610 | The user has no account yet; `setup_account` creates it. |\n| 429 | 670, 680 | Too many requests to the account or billing service; try again later. |\n| 500 | 690 | An internal error; try again later. |\n| 502 | 671, 672, 681, 682 | The account or billing service failed; try again later. |\n\nEach operation's `default` response names its other codes:\n\n| Status | Code | Reason | When |\n| --- | --- | --- | --- |\n| 401 | 604 |  | The sign-in code or refresh token is invalid or expired. Sign in again. |\n| 409 | 605 |  | This email address is not available. |\n| 400 | 606 |  | The email change code is incorrect. Check it, or request a new code. |\n| 404 | 607 |  | Sign-in session not found. |\n| 409 | 611 |  | The person with this email already belongs to a Tardis.dev account. |\n| 409 | 612 |  | This user belongs to more than one Tardis.dev account. Contact support. |\n| 403 | 613 |  | This account is disabled. Contact support. |\n| 409 | 620 | `active_subscription` | This account already has an active subscription. Upgrade it instead. |\n| 409 | 620 | `invoice_unpaid` | This account has an invoice awaiting payment. Pay it, or cancel its subscription, first. |\n| 409 | 620 | `payment_overdue` | A subscription has an overdue payment. Pay its invoice or update its payment method, then try again. |\n| 404 | 621 |  | Subscription not found. |\n| 409 | 622 | `awaiting_payment` | This subscription is awaiting payment of its first invoice. Until it is paid, it can only be canceled. |\n| 409 | 622 | `invoice_unpaid` | This subscription has an invoice awaiting payment. Try again after it is paid. |\n| 409 | 622 | `not_resumable` | This subscription can no longer be renewed. Start a new subscription instead. |\n| 409 | 622 | `older_subscription` | Older subscriptions cannot be paid by invoicing or paused. |\n| 409 | 622 | `paid_by_invoicing` | This subscription is paid by invoicing, not by card or PayPal. |\n| 409 | 622 | `payment_overdue` | A subscription has an overdue payment. Pay its invoice or update its payment method, then try again. |\n| 409 | 622 | `renewal_pending` | This subscription renews within 30 minutes. Try again after the renewal. |\n| 409 | 622 | `subscription_canceled` | This subscription is canceled. Resume it first if it hasn’t ended yet. |\n| 409 | 622 | `subscription_inactive` | Only active subscriptions can be changed. |\n| 403 | 623 |  | Sign in with a verified university email address to purchase an Academic subscription. |\n| 403 | 624 |  | Academic subscriptions are not available for your location or email domain. |\n| 404 | 625 |  | Invoice not found. |\n| 409 | 627 |  | This invoice can no longer be revised. |\n| 409 | 628 |  | Save the billing details with `update_billing_details` first. |\n| 409 | 630 |  | This account has reached its Data API key limit. Revoke a key, or wait until a replaced key expires. |\n| 404 | 631 |  | Data API key not found. |\n| 403 | 632 |  | Active data access is required to view Data API usage. |\n| 429 | 633 |  | This account has rotated 3 Data API keys in the last 24 hours. Try again later, or revoke a key and create a new one. |\n| 400 | 640 |  | A free trial is not available for this account or user. |\n| 429 | 641 |  | No more free trials can start today. Try again tomorrow. |\n| 404 | 650 |  | Account member not found. |\n| 403 | 651 |  | Only another owner can change your role or remove you. |\n| 404 | 652 |  | Invitation not found. It may have been accepted, revoked or expired. |\n| 429 | 653 |  | This account has sent 5 invitations in the last 24 hours. Try again later. |\n| 409 | 654 |  | This email already has a pending invitation to this account. Revoke it to send a new one. |\n| 402 | 660 |  | Payment failed. Update the payment method, then try again. |\n| 409 | 661 |  | The subscription change could not be completed. Contact support before retrying. |"},"tags":[{"name":"Authentication","description":"Browser sign-in for the website and CLIs."},{"name":"User","description":"Name, login email and sign-in sessions."},{"name":"Account","description":"Name, status and data access."},{"name":"Data API","description":"Keys, usage and limits."},{"name":"Members","description":"Members, roles and invitations."},{"name":"Billing","description":"Plans, subscriptions, invoices, billing details and the free trial."},{"name":"Exchanges","description":"Exchanges and symbols with historical data."}],"servers":[{"url":"https://api.tardis.dev"}],"externalDocs":{"description":"Authorization guide","url":"https://api.tardis.dev/auth.md"},"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"DataAccess":{"type":"object","properties":{"type":{"enum":["subscription","trial","one-off-purchase"],"type":"string"},"name":{"type":"string","description":"Plan name, or `Free trial`."},"subscriptionId":{"type":"string"},"subscriptionType":{"enum":["academic","solo","professional","business"],"type":"string"},"dataPlan":{"enum":["perpetuals","options","spot","derivatives","all-exchanges","legacy"],"type":"string"},"from":{"type":"string","format":"date-time","description":"Inclusive start of the data range."},"to":{"type":"string","format":"date-time","description":"Exclusive end of the data range."},"expiresAt":{"type":"string","format":"date-time","description":"When a trial or one-off purchase ends. Omitted for subscriptions."}},"required":["type","name","dataPlan","from","to"]},"Account":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","description":"Starts as the creator's company email domain, or their email address on a public email provider."},"status":{"enum":["active","disabled"],"type":"string","description":"`disabled` accounts cannot use the Data API or make purchases; contact support to restore one."},"trialAvailable":{"type":"boolean","description":"Whether to offer the free trial."},"dataAccess":{"type":"array","items":{"$ref":"#/components/schemas/DataAccess"},"description":"Data the account can download now."}},"required":["id","name","status","trialAvailable","dataAccess"]},"AccountError":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string","description":"Explanation for people, which can change. Use `code` and `reason` in code."},"reason":{"enum":["role_required","permission_missing","active_subscription","invoice_unpaid","payment_overdue","awaiting_payment","subscription_canceled","subscription_inactive","older_subscription","not_resumable","paid_by_invoicing","renewal_pending"],"type":"string","description":"Which condition caused a `601` (see Permissions), `620` or `622` (see Errors)."},"field":{"type":"string","description":"The request field that is wrong: on `110` when one field fails validation, and on `627` for the billing detail that a revision cannot change."},"requiredPermission":{"enum":["user:read","user:write","account:read","account:write","data_api_keys:read","data_api_keys:write","members:read","members:write","billing:read","billing:write"],"type":"string","description":"On `601`: the permission the operation needs."},"roles":{"type":"array","items":{"enum":["owner","billing","member"],"type":"string"},"description":"On `601` with `role_required`: the roles that have `requiredPermission`."},"missingFields":{"type":"array","items":{"type":"string"},"description":"On `628`: the billing details to save with `update_billing_details` first."},"invoiceId":{"type":"string","description":"With `invoice_unpaid` and `awaiting_payment`: the unpaid invoice."},"subscriptionId":{"type":"string","description":"With `payment_overdue`: the subscription to pay, for example with `create_payment_method_update_link`. With `active_subscription`: a paused or canceled subscription to resume instead."}},"required":["code","message"]},"BillingPlanChoice":{"type":"object","properties":{"subscriptionType":{"enum":["academic","solo","professional","business"],"type":"string"},"billingInterval":{"enum":["monthly","quarterly","yearly"],"type":"string"},"dataPlan":{"enum":["perpetuals","options","spot","derivatives","all-exchanges"],"type":"string"}},"required":["subscriptionType","billingInterval","dataPlan"]},"BillingDetails":{"type":"object","properties":{"email":{"type":"string","description":"Receives invoices and receipts. Starts as the login of whoever first buys or saves the billing details, and changes only with `update_billing_details`."},"additionalBillingEmails":{"type":"array","items":{"type":"string"},"description":"Also receive invoices and receipts."},"name":{"type":"string"},"countryCode":{"type":"string"},"addressLine":{"type":"string"},"city":{"type":"string"},"postalCode":{"type":"string"},"region":{"type":"string"},"taxId":{"type":"string"},"companyNumber":{"type":"string"},"purchaseOrderNumber":{"type":"string"},"additionalBillingEmailDomain":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Domain that a new `email` other than the current user's login and new `additionalBillingEmails` must use: the company domain of the current user's verified login. Null when the login has none, for example at a public email provider or a university."}},"required":["additionalBillingEmailDomain"]},"Invoice":{"type":"object","properties":{"type":{"const":"invoice"},"id":{"type":"string"},"status":{"enum":["draft","issued","overdue","paid","canceled"],"type":"string","description":"`draft`: not sent; a newer draft replaces it. `overdue`: not paid a day after `dueAt`. A refunded invoice stays `paid`. `canceled`: canceled after it was sent."},"invoiceNumber":{"type":"string","description":"Number to quote in the bank transfer. Omitted for drafts."},"subscriptionId":{"type":"string","description":"Omitted for drafts."},"collectionMode":{"enum":["automatic","invoicing"],"type":"string","description":"`automatic`: charged to the saved card or PayPal account. `invoicing`: invoiced by email and paid by bank transfer."},"name":{"type":"string"},"subscriptionType":{"enum":["academic","solo","professional","business"],"type":"string"},"billingInterval":{"enum":["monthly","quarterly","yearly"],"type":"string"},"dataPlan":{"enum":["perpetuals","options","spot","derivatives","all-exchanges"],"type":"string"},"currency":{"const":"USD"},"subtotal":{"type":"number"},"tax":{"type":"number"},"taxRate":{"type":"number","description":"A fraction, for example `0.23`."},"total":{"type":"number","description":"Amount due: `subtotal` plus `tax`, less `creditTotal`."},"refundTotal":{"type":"number","description":"Refunded or charged back, including tax. Paddle emails a credit note for each refund."},"creditTotal":{"type":"number","description":"Credited before payment, for example the tax once `revise_invoice` adds a valid VAT number."},"paymentTermsDays":{"type":"integer"},"issuedAt":{"type":"string","format":"date-time"},"dueAt":{"type":"string","format":"date-time","description":"Invoicing only."},"paidAt":{"type":"string","format":"date-time","description":"Omitted while unpaid and when nothing was charged."},"revisedAt":{"type":"string","format":"date-time"},"billingDetails":{"type":"object","properties":{"email":{"type":"string","description":"Address the invoice was sent to."},"additionalBillingEmails":{"type":"array","items":{"type":"string"},"description":"Also receive invoices and receipts."},"name":{"type":"string"},"countryCode":{"type":"string"},"addressLine":{"type":"string"},"city":{"type":"string"},"postalCode":{"type":"string"},"region":{"type":"string"},"taxId":{"type":"string"},"companyNumber":{"type":"string"},"purchaseOrderNumber":{"type":"string"}},"required":[],"description":"As printed on the invoice."}},"required":["type","id","status","collectionMode","name","subscriptionType","billingInterval","dataPlan","currency","subtotal","tax","taxRate","total","billingDetails"]},"Subscription":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","description":"For example `Perpetuals Professional Subscription`."},"subscriptionType":{"enum":["academic","solo","professional","business"],"type":"string"},"billingInterval":{"enum":["monthly","quarterly","yearly"],"type":"string"},"dataPlan":{"enum":["perpetuals","options","spot","derivatives","all-exchanges","legacy"],"type":"string"},"renewalTotal":{"type":"number","description":"Each renewal payment, which resuming a `paused` subscription charges at once. Omitted once a cancellation is scheduled."},"currency":{"const":"USD"},"startedAt":{"type":"string","format":"date-time","description":"Day the first payment started the subscription. Omitted until then."},"renewsAt":{"type":"string","format":"date-time","description":"UTC day. Omitted when the subscription will not renew."},"collectionMode":{"enum":["automatic","invoicing"],"type":"string","description":"`automatic`: charged to the saved card or PayPal account. `invoicing`: invoiced by email and paid by bank transfer."},"billingSystem":{"enum":["paddle_billing","paddle_classic"],"type":"string","description":"`paddle_classic`: an older subscription."},"paymentMethod":{"type":"object","properties":{"type":{"enum":["card","paypal","apple_pay","google_pay","other"],"type":"string","description":"`other`: none of the others."},"card":{"type":"object","properties":{"brand":{"type":"string","description":"For example `visa`, `mastercard` or `american_express`."},"last4":{"type":"string"}},"required":["brand","last4"]}},"required":["type"],"description":"What paid the latest payment, for example `{ \"type\": \"card\", \"card\": { \"brand\": \"visa\", \"last4\": \"4242\" } }` or `{ \"type\": \"paypal\" }`. Omitted for `invoicing`, for older subscriptions and once a cancellation is scheduled."},"status":{"enum":["awaiting_payment","active","past_due","cancellation_scheduled","pause_scheduled","canceled","paused","trialing"],"type":"string","description":"`awaiting_payment`: the first invoice is sent and unpaid; data access starts when it is paid, and the subscription ends if it is not paid a day after its due date. `active`: paid and renewing. `past_due`: a renewal payment is overdue; data access stops at the end of the renewal day (UTC) for a card, or at the end of the invoice’s due date (UTC) for an invoice, and returns when it is paid. `cancellation_scheduled`: will not renew; data access lasts until `dataAccess.to`, and `resume_subscription` undoes the cancellation until then. `pause_scheduled`: like `cancellation_scheduled`, but it pauses instead of ending; yearly subscriptions paid by card start this way. `paused`: data access ends with the paid period, at the end of the renewal day (UTC); `resume_subscription` starts a new billing period, charged at once. `canceled`: final; remaining data access lasts until `dataAccess.to`, unless a refund or chargeback ends it. `trialing`: older subscriptions only."},"unpaidInvoice":{"type":"object","properties":{"id":{"type":"string"},"total":{"type":"number"},"dueAt":{"type":"string","format":"date-time"},"reason":{"enum":["purchase","renewal","upgrade"],"type":"string","description":"`upgrade`: the new plan starts when it is paid."},"upgradeTo":{"type":"string","description":"Name of the plan after the upgrade."}},"required":["id","total","dueAt","reason"],"description":"The unpaid invoice of this subscription. For a `renewal`, data access lasts until `dueAt`."},"dataAccess":{"type":"object","properties":{"active":{"type":"boolean"},"from":{"type":"string","format":"date-time","description":"Inclusive start of the data range. Set once the first invoice is sent; access starts when it is paid."},"to":{"type":"string","format":"date-time","description":"Exclusive end of the data range."}},"required":["active"]},"canceledAt":{"type":"string","format":"date-time"}},"required":["id","name","subscriptionType","billingInterval","dataPlan","currency","collectionMode","billingSystem","status","dataAccess"]},"DataApiKeyIpLock":{"type":"object","properties":{"ipAddress":{"type":"string"},"countryCode":{"type":"string"},"city":{"type":"string"},"lastUsedAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time","description":"When another IP address can take the key over, unless a request from `ipAddress` extends it."},"blockedIpAddresses":{"type":"array","items":{"type":"object","properties":{"ipAddress":{"type":"string"},"countryCode":{"type":"string"},"city":{"type":"string"},"lastBlockedAt":{"type":"string","format":"date-time"}},"required":["ipAddress","lastBlockedAt"]},"description":"Refused IP addresses, latest first."}},"required":["ipAddress","lastUsedAt","expiresAt","blockedIpAddresses"],"description":"Except on a Business subscription, one IP address at a time can use each key. Present while the key is locked to an address."},"DataApiKeyWithSecret":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"keyPrefix":{"type":"string","description":"First characters of the secret."},"createdAt":{"type":"string","format":"date-time"},"status":{"enum":["active","replaced"],"type":"string","description":"`replaced`: rotated, and works until `expiresAt`."},"expiresAt":{"type":"string","format":"date-time"},"ipLock":{"$ref":"#/components/schemas/DataApiKeyIpLock"},"secret":{"type":"string","description":"See the [Data API quickstart](https://docs.tardis.dev/api/quickstart) and [downloadable CSV files](https://docs.tardis.dev/downloadable-csv-files/overview)."}},"required":["id","name","keyPrefix","createdAt","status","secret"]},"Member":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"role":{"enum":["owner","billing","member"],"type":"string"}},"required":["id","email","firstName","lastName","role"]},"Invitation":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string","format":"email"},"role":{"enum":["owner","billing","member"],"type":"string"},"expiresAt":{"type":"string","format":"date-time"}},"required":["id","email","role","expiresAt"]},"SignInTokens":{"type":"object","properties":{"accessToken":{"type":"string","description":"Expires after a few minutes."},"refreshToken":{"type":"string"},"account":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","description":"Starts as the creator's company email domain, or their email address on a public email provider."},"status":{"enum":["active","disabled"],"type":"string","description":"`disabled` accounts cannot use the Data API or make purchases; contact support to restore one."}},"required":["id","name","status"]}},"required":["accessToken","refreshToken","account"]},"User":{"type":"object","properties":{"id":{"type":"string","description":"Member `id` of the user, as in `list_members`."},"email":{"type":"string","format":"email","description":"Login email."},"firstName":{"anyOf":[{"type":"string"},{"type":"null"}]},"lastName":{"anyOf":[{"type":"string"},{"type":"null"}]},"role":{"enum":["owner","billing","member"],"type":"string"},"permissions":{"type":"array","items":{"enum":["user:read","user:write","account:read","account:write","data_api_keys:read","data_api_keys:write","members:read","members:write","billing:read","billing:write"],"type":"string"},"description":"Permissions of this access token, within those of `role`."}},"required":["id","email","firstName","lastName","role","permissions"]}},"parameters":{"dataApiKeyId":{"name":"dataApiKeyId","in":"path","required":true,"schema":{"type":"string","minLength":1,"description":"Key `id` from `list_data_api_keys`."}},"memberId":{"name":"memberId","in":"path","required":true,"schema":{"type":"string","minLength":1,"description":"Member `id` from `list_members`."}},"subscriptionId":{"name":"subscriptionId","in":"path","required":true,"schema":{"type":"string","minLength":1,"description":"Subscription `id` from `list_subscriptions`."}},"invoiceId":{"name":"invoiceId","in":"path","required":true,"schema":{"type":"string","minLength":1,"pattern":"^txn_[a-z0-9]{26}$","description":"Invoice `id` from `list_invoices` or `create_subscription_invoice`."}}},"responses":{"AccountError":{"description":"An error; see Errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountError"}}}}}},"paths":{"/v1/auth/sign-in":{"post":{"operationId":"start_sign_in","tags":["Authentication"],"summary":"Start signing in","description":"Open `authorizationUrl` in a browser; after sign-in it returns to `redirectUri` with a `code` for `complete_sign_in`.","security":[],"responses":{"200":{"description":"Sign-in page","content":{"application/json":{"schema":{"type":"object","properties":{"authorizationUrl":{"type":"string","format":"uri"}},"required":["authorizationUrl"]}}}},"default":{"$ref":"#/components/responses/AccountError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"redirectUri":{"type":"string","minLength":1},"codeChallenge":{"type":"string","minLength":1,"description":"S256 PKCE challenge."},"state":{"type":"string","minLength":1},"loginHint":{"type":"string","description":"Email to prefill."}},"required":["redirectUri","codeChallenge","state"]}}}}}},"/v1/auth/sign-in/complete":{"post":{"operationId":"complete_sign_in","tags":["Authentication"],"summary":"Complete signing in","description":"Creates the user's account at their first sign-in.","security":[],"responses":{"200":{"description":"Tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignInTokens"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`604`, `612`, or a common error; see Errors."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","minLength":1},"codeVerifier":{"type":"string","minLength":1}},"required":["code","codeVerifier"]}}}}}},"/v1/auth/sign-in/refresh":{"post":{"operationId":"refresh_sign_in","tags":["Authentication"],"summary":"Refresh tokens","description":"Returns new tokens; the old refresh token stops working.","security":[],"responses":{"200":{"description":"Tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignInTokens"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`604`, `612`, or a common error; see Errors."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"refreshToken":{"type":"string","minLength":1}},"required":["refreshToken"]}}}}}},"/v1/auth/sign-out":{"post":{"operationId":"sign_out","tags":["Authentication"],"summary":"Sign out","description":"Ends the sign-in session of this access token; the access token itself works until it expires. Agent authorizations stay.","responses":{"204":{"description":"Signed out"},"default":{"$ref":"#/components/responses/AccountError"}}}},"/v1/account":{"post":{"operationId":"setup_account","tags":["Account"],"summary":"Set up the account","description":"Creates the user's account when they have none, then returns it. Agents: call it once after authorization.","security":[{"bearerAuth":["account:read"]}],"responses":{"200":{"description":"Existing account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"201":{"description":"Account created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`612`, or a common error; see Errors."}}},"get":{"operationId":"get_account","tags":["Account"],"summary":"Get the account","security":[{"bearerAuth":["account:read"]}],"responses":{"200":{"description":"Account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"default":{"$ref":"#/components/responses/AccountError"}}},"patch":{"operationId":"update_account","tags":["Account"],"summary":"Rename the account","security":[{"bearerAuth":["account:write"]}],"responses":{"200":{"description":"Account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"default":{"$ref":"#/components/responses/AccountError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100}},"required":["name"]}}}}}},"/v1/user":{"get":{"operationId":"get_user","tags":["User"],"summary":"Get the current user","security":[{"bearerAuth":["user:read"]}],"responses":{"200":{"description":"Current user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"default":{"$ref":"#/components/responses/AccountError"}}},"patch":{"operationId":"update_user","tags":["User"],"summary":"Update the current user","security":[{"bearerAuth":["user:write"]}],"responses":{"200":{"description":"Current user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"default":{"$ref":"#/components/responses/AccountError"}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"firstName":{"type":"string","minLength":1,"maxLength":100},"lastName":{"type":"string","minLength":1,"maxLength":100}},"required":[]}}}}}},"/v1/user/email-change":{"post":{"operationId":"start_email_change","tags":["User"],"summary":"Start an email change","description":"Emails a code to the new address for `confirm_email_change`.","security":[{"bearerAuth":["user:write"]}],"responses":{"204":{"description":"Verification code sent"},"default":{"$ref":"#/components/responses/AccountError","description":"`605`, or a common error; see Errors."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","minLength":1,"format":"email"}},"required":["email"]}}}}}},"/v1/user/email-change/confirm":{"post":{"operationId":"confirm_email_change","tags":["User"],"summary":"Confirm an email change","description":"When the old login is the billing email, the billing email changes to the new login.","security":[{"bearerAuth":["user:write"]}],"responses":{"200":{"description":"Updated user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`606`, or a common error; see Errors."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"code":{"type":"string","minLength":1}},"required":["code"]}}}}}},"/v1/user/sessions":{"get":{"operationId":"list_user_sessions","tags":["User"],"summary":"List sign-in sessions","description":"Agent authorizations are not listed.","security":[{"bearerAuth":["user:read"]}],"responses":{"200":{"description":"Sign-in sessions","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"current":{"type":"boolean","description":"Whether the request was made with this session."},"ipAddress":{"anyOf":[{"type":"string"},{"type":"null"}]},"userAgent":{"anyOf":[{"type":"string"},{"type":"null"}]},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}},"required":["id","current","ipAddress","userAgent","createdAt","expiresAt"]}}}}},"default":{"$ref":"#/components/responses/AccountError"}}},"delete":{"operationId":"revoke_all_user_sessions","tags":["User"],"summary":"Sign out everywhere","description":"Includes the session of this request. Agent authorizations stay.","security":[{"bearerAuth":["user:write"]}],"responses":{"204":{"description":"Sessions ended"},"default":{"$ref":"#/components/responses/AccountError"}}}},"/v1/user/sessions/{sessionId}":{"delete":{"operationId":"revoke_user_session","tags":["User"],"summary":"Sign out a session","description":"Its access token works until it expires and cannot be refreshed.","security":[{"bearerAuth":["user:write"]}],"responses":{"204":{"description":"Session ended"},"default":{"$ref":"#/components/responses/AccountError","description":"`607`, or a common error; see Errors."}},"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string","minLength":1,"description":"Session `id` from `list_user_sessions`."}}]}},"/v1/account/data-api-keys":{"get":{"operationId":"list_data_api_keys","tags":["Data API"],"summary":"List Data API keys","description":"Only keys that still work, oldest first.","security":[{"bearerAuth":["data_api_keys:read"]}],"responses":{"200":{"description":"Data API keys","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"keyPrefix":{"type":"string","description":"First characters of the secret."},"createdAt":{"type":"string","format":"date-time"},"status":{"enum":["active","replaced"],"type":"string","description":"`replaced`: rotated, and works until `expiresAt`."},"expiresAt":{"type":"string","format":"date-time"},"ipLock":{"$ref":"#/components/schemas/DataApiKeyIpLock"},"createdBy":{"type":"string","description":"Email of the person who created the key, directly or through an agent. Omitted when Tardis.dev created it."}},"required":["id","name","keyPrefix","createdAt","status"]}}}}},"default":{"$ref":"#/components/responses/AccountError"}}},"post":{"operationId":"create_data_api_key","tags":["Data API"],"summary":"Create a Data API key","description":"Returns `secret` only this once. Agents: store it securely, never log it, and show it only when the user asks.","security":[{"bearerAuth":["data_api_keys:write"]}],"responses":{"201":{"description":"Created Data API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataApiKeyWithSecret"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`630`, or a common error; see Errors."}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Defaults to `Data API key`."}},"required":[]}}}}}},"/v1/account/data-api-keys/{dataApiKeyId}/rotate":{"post":{"operationId":"rotate_data_api_key","tags":["Data API"],"summary":"Rotate a Data API key","description":"Creates a new key and returns its `secret` only this once. The old key becomes `replaced` and works for one more hour. An account can rotate keys 3 times in 24 hours. Agents: store the secret securely, never log it, and show it only when the user asks.","security":[{"bearerAuth":["data_api_keys:write"]}],"responses":{"201":{"description":"Replacement Data API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataApiKeyWithSecret"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`630`, `631`, `633`, or a common error; see Errors."}},"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","description":"Defaults to the old key's name."}},"required":[]}}}},"parameters":[{"$ref":"#/components/parameters/dataApiKeyId"}]}},"/v1/account/data-api-keys/{dataApiKeyId}":{"delete":{"operationId":"revoke_data_api_key","tags":["Data API"],"summary":"Revoke a Data API key","description":"The key stops working at once, a `replaced` one too.","security":[{"bearerAuth":["data_api_keys:write"]}],"responses":{"204":{"description":"Data API key revoked"},"default":{"$ref":"#/components/responses/AccountError","description":"`631`, or a common error; see Errors."}},"parameters":[{"$ref":"#/components/parameters/dataApiKeyId"}]}},"/v1/account/data-api-usage":{"get":{"operationId":"get_data_api_usage","tags":["Data API"],"summary":"Get Data API usage and limits","description":"Needs data access.","security":[{"bearerAuth":["account:read"]}],"responses":{"200":{"description":"Usage and limits","content":{"application/json":{"schema":{"type":"object","properties":{"dataTransfer":{"type":"object","properties":{"usedBytes":{"type":"number","description":"Compressed bytes downloaded since `periodStartedAt`."},"limitBytes":{"type":"number"},"periodStartedAt":{"type":"string","format":"date-time"},"resetsAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Null when the account has only a trial, whose period never resets."}},"required":["usedBytes","limitBytes","periodStartedAt","resetsAt"]},"dataFeedRequestRateLimit":{"type":"object","properties":{"limit":{"type":"number"},"windowSeconds":{"type":"number"}},"required":["limit","windowSeconds"]},"dataApiKeyLimit":{"type":"number","description":"Keys that can work at once; a `replaced` key counts until it expires."}},"required":["dataTransfer","dataFeedRequestRateLimit","dataApiKeyLimit"]}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`613`, `632`, or a common error; see Errors."}}}},"/v1/account/members":{"get":{"operationId":"list_members","tags":["Members"],"summary":"List members","security":[{"bearerAuth":["members:read"]}],"responses":{"200":{"description":"Members","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Member"}}}}},"default":{"$ref":"#/components/responses/AccountError"}}}},"/v1/account/members/{memberId}":{"patch":{"operationId":"update_member","tags":["Members"],"summary":"Change a member's role","description":"Only another owner can change your own role.","security":[{"bearerAuth":["members:write"]}],"responses":{"200":{"description":"Member","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Member"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`650`, `651`, or a common error; see Errors."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"enum":["owner","billing","member"],"type":"string"}},"required":["role"]}}}},"parameters":[{"$ref":"#/components/parameters/memberId"}]},"delete":{"operationId":"remove_member","tags":["Members"],"summary":"Remove a member","description":"Only another owner can remove you. When the member's login is the billing email, it keeps receiving invoices and receipts until `update_billing_details` changes it. Data API keys they created keep working.","security":[{"bearerAuth":["members:write"]}],"responses":{"204":{"description":"Member removed"},"default":{"$ref":"#/components/responses/AccountError","description":"`650`, `651`, or a common error; see Errors."}},"parameters":[{"$ref":"#/components/parameters/memberId"}]}},"/v1/account/invitations":{"get":{"operationId":"list_invitations","tags":["Members"],"summary":"List pending invitations","security":[{"bearerAuth":["members:read"]}],"responses":{"200":{"description":"Pending invitations","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Invitation"}}}}},"default":{"$ref":"#/components/responses/AccountError"}}},"post":{"operationId":"invite_member","tags":["Members"],"summary":"Invite a member","description":"A person who already belongs to a Tardis.dev account, this one included, cannot be invited. An email with a pending invitation can be invited again once that invitation is revoked. An account can invite 5 times in 24 hours, refused attempts included.","security":[{"bearerAuth":["members:write"]}],"responses":{"201":{"description":"Invitation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invitation"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`611`, `612`, `613`, `653`, `654`, or a common error; see Errors."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","minLength":1,"format":"email"},"role":{"enum":["owner","billing","member"],"type":"string","default":"member"}},"required":["email"]}}}}}},"/v1/account/invitations/{invitationId}":{"delete":{"operationId":"revoke_invitation","tags":["Members"],"summary":"Revoke an invitation","security":[{"bearerAuth":["members:write"]}],"responses":{"204":{"description":"Invitation revoked"},"default":{"$ref":"#/components/responses/AccountError","description":"`652`, or a common error; see Errors."}},"parameters":[{"name":"invitationId","in":"path","required":true,"schema":{"type":"string","minLength":1,"description":"Invitation `id` from `list_invitations`."}}]}},"/v1/plans":{"get":{"operationId":"list_plans","tags":["Billing"],"summary":"List plans","description":"Prices exclude tax. Academic plans are listed only where they are available. To buy a billing plan or upgrade to it, pass its `subscriptionType`, `billingInterval` and `dataPlan`.","security":[],"responses":{"200":{"description":"Plans","content":{"application/json":{"schema":{"type":"object","properties":{"subscriptionTypes":{"type":"array","items":{"type":"object","properties":{"id":{"enum":["academic","solo","professional","business"],"type":"string"},"name":{"type":"string"},"connectivity":{"enum":["standard","cloudflare-argo-smart-routing"],"type":"string","description":"Routing of API requests; `cloudflare-argo-smart-routing` is Premium Connectivity."},"downloadableCsvFiles":{"type":"boolean"},"dataFeedApi":{"type":"boolean"},"tardisMachineReplay":{"type":"boolean"},"instrumentMetadataApi":{"type":"boolean"},"dataApiKeyLimit":{"type":"integer"},"dataFeedRequestRateLimit":{"type":"object","properties":{"limit":{"type":"integer"},"windowSeconds":{"type":"integer"}},"required":["limit","windowSeconds"]},"supportResponseHours":{"type":"integer","description":"Target time to the first email support reply."}},"required":["id","name","connectivity","downloadableCsvFiles","dataFeedApi","tardisMachineReplay","instrumentMetadataApi","dataApiKeyLimit","supportResponseHours"]}},"dataPlans":{"type":"array","items":{"type":"object","properties":{"id":{"enum":["perpetuals","options","spot","derivatives","all-exchanges"],"type":"string"},"name":{"type":"string"},"exchanges":{"type":"array","items":{"type":"string"},"description":"Exchange ids, as in the Data API."}},"required":["id","name","exchanges"]}},"billingPlans":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"For example `Perpetuals Professional Subscription`."},"subscriptionType":{"enum":["academic","solo","professional","business"],"type":"string","description":"`id` of an item in `subscriptionTypes`."},"billingInterval":{"enum":["monthly","quarterly","yearly"],"type":"string"},"dataPlan":{"enum":["perpetuals","options","spot","derivatives","all-exchanges"],"type":"string","description":"`id` of an item in `dataPlans`."},"fullHistory":{"type":"boolean","description":"Includes all history; otherwise `backHistoryMonths` applies."},"backHistoryMonths":{"type":"integer","description":"Months of history before the start date; the range grows with each renewal."},"dataTransferLimitBytes":{"type":"integer","description":"Compressed, per billing interval."},"price":{"type":"number","description":"For one billing interval."},"currency":{"const":"USD"},"invoicing":{"type":"object","properties":{"paymentTermsDays":{"type":"integer"},"historyBonusMonths":{"type":"integer","description":"Months added to `backHistoryMonths`."}},"required":["paymentTermsDays","historyBonusMonths"],"description":"Omitted for monthly plans, which only card or PayPal can pay."}},"required":["name","subscriptionType","billingInterval","dataPlan","fullHistory","dataTransferLimitBytes","price","currency"]}}},"required":["subscriptionTypes","dataPlans","billingPlans"]}}}},"default":{"$ref":"#/components/responses/AccountError"}}}},"/v1/account/subscriptions":{"get":{"operationId":"list_subscriptions","tags":["Billing"],"summary":"List subscriptions","description":"Includes ended subscriptions, except one canceled before its first invoice was paid.","security":[{"bearerAuth":["billing:read"]}],"responses":{"200":{"description":"Subscriptions","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Subscription"}}}}},"default":{"$ref":"#/components/responses/AccountError"}}}},"/v1/account/subscriptions/{subscriptionId}/change/preview":{"post":{"operationId":"preview_subscription_change","tags":["Billing"],"summary":"Preview a subscription upgrade","description":"Shows what `change_subscription` would do. Only upgrades are possible: the new plan keeps or raises the subscription type, data plan and billing interval, and costs more. The full price difference for the current billing period is due at once, however much of the period is left. The renewal date moves only for a longer billing interval. Needs an active subscription without an unpaid invoice.","security":[{"bearerAuth":["billing:write"]}],"responses":{"200":{"description":"Upgrade preview","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"subscriptionType":{"enum":["academic","solo","professional","business"],"type":"string"},"billingInterval":{"enum":["monthly","quarterly","yearly"],"type":"string"},"dataPlan":{"enum":["perpetuals","options","spot","derivatives","all-exchanges"],"type":"string"},"renewalTotal":{"type":"number","description":"Each renewal of the new plan."},"currency":{"const":"USD"},"immediateTotal":{"type":"number","description":"Due now."},"immediateTax":{"type":"number","description":"Omitted when Paddle does not report it in advance."},"renewsAt":{"type":"string","format":"date-time","description":"First renewal of the new plan."},"dataAccess":{"type":"object","properties":{"from":{"type":"string","format":"date-time","description":"Inclusive start of the data range."},"to":{"type":"string","format":"date-time","description":"Exclusive end of the data range."}},"required":["from","to"]}},"required":["id","name","subscriptionType","billingInterval","dataPlan","renewalTotal","currency","immediateTotal","renewsAt","dataAccess"]}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`621`, `622` (`awaiting_payment`, `invoice_unpaid`, `payment_overdue`, `renewal_pending`, `subscription_canceled`, `subscription_inactive`), or a common error; see Errors."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPlanChoice"}}}},"parameters":[{"$ref":"#/components/parameters/subscriptionId"}]}},"/v1/account/subscriptions/{subscriptionId}/change":{"post":{"operationId":"change_subscription","tags":["Billing"],"summary":"Upgrade a subscription","description":"Upgrades as `preview_subscription_change` shows: a card is charged and the new plan starts at once; with invoicing, an invoice is emailed and the new plan starts when it is paid (`unpaidInvoice.reason: upgrade`). Agents: preview first, confirm the plan and amount with the user, and tell them the payment cannot be refunded once they download or use the data.","security":[{"bearerAuth":["billing:write"]}],"responses":{"200":{"description":"Subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`621`, `622` (`awaiting_payment`, `invoice_unpaid`, `payment_overdue`, `renewal_pending`, `subscription_canceled`, `subscription_inactive`), `660`, `661`, or a common error; see Errors."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPlanChoice"}}}},"parameters":[{"$ref":"#/components/parameters/subscriptionId"}]}},"/v1/account/subscriptions/{subscriptionId}/cancel":{"post":{"operationId":"cancel_subscription","tags":["Billing"],"summary":"Cancel a subscription","description":"Cancels at the end of the paid period: data access lasts until `dataAccess.to`, and `resume_subscription` undoes the cancellation until then. An `awaiting_payment` subscription ends at once with its invoice, and a `past_due` or `paused` one ends at once, stopping payment attempts; these are final. An older subscription returns `202` with `confirmationUrl`, a Paddle page where the user confirms the cancellation. Agents: confirm with the user first.","security":[{"bearerAuth":["billing:write"]}],"responses":{"200":{"description":"Canceled subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}}},"202":{"description":"Cancellation awaiting confirmation","content":{"application/json":{"schema":{"type":"object","properties":{"confirmationUrl":{"type":"string","format":"uri","description":"The subscription stays unchanged until the user confirms."}},"required":["confirmationUrl"]}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`621`, `622` (`subscription_canceled`), or a common error; see Errors."}},"parameters":[{"$ref":"#/components/parameters/subscriptionId"}]}},"/v1/account/subscriptions/{subscriptionId}/pause":{"post":{"operationId":"pause_subscription","tags":["Billing"],"summary":"Pause a subscription","description":"Stops the renewal of a subscription paid by card or PayPal: data access lasts until `dataAccess.to`, then the subscription pauses. `resume_subscription` renews it again, before or after it pauses. Agents: confirm with the user first.","security":[{"bearerAuth":["billing:write"]}],"responses":{"200":{"description":"Subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`621`, `622` (`awaiting_payment`, `older_subscription`, `paid_by_invoicing`, `payment_overdue`, `renewal_pending`, `subscription_canceled`), or a common error; see Errors."}},"parameters":[{"$ref":"#/components/parameters/subscriptionId"}]}},"/v1/account/subscriptions/{subscriptionId}/resume":{"post":{"operationId":"resume_subscription","tags":["Billing"],"summary":"Resume a subscription","description":"Undoes a scheduled cancellation or pause. A `paused` subscription starts a new billing period, charged `renewalTotal` at once; data access returns seconds after the payment, with `dataAccess.from` moved forward by the paused time, and a failed payment leaves it `past_due`. Fails while the account has another active subscription or an unpaid invoice. Agents: confirm with the user first, with the amount for a `paused` one.","security":[{"bearerAuth":["billing:write"]}],"responses":{"200":{"description":"Subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`613`, `620` (`active_subscription`, `invoice_unpaid`, `payment_overdue`), `621`, `622` (`awaiting_payment`, `not_resumable`), or a common error; see Errors."}},"parameters":[{"$ref":"#/components/parameters/subscriptionId"}]}},"/v1/account/subscriptions/{subscriptionId}/switch-to-invoicing":{"post":{"operationId":"switch_subscription_to_invoicing","tags":["Billing"],"summary":"Switch a subscription to invoicing","description":"From its next renewal, a quarterly or yearly subscription is paid by invoicing with the saved billing details. Data access lasts until each invoice is due, and invoicing adds history. A scheduled pause is removed. Agents: confirm with the user first.","security":[{"bearerAuth":["billing:write"]}],"responses":{"200":{"description":"Subscription","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Subscription"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`621`, `622` (`awaiting_payment`, `older_subscription`, `paid_by_invoicing`, `payment_overdue`, `renewal_pending`, `subscription_canceled`, `subscription_inactive`), `628`, or a common error; see Errors."}},"parameters":[{"$ref":"#/components/parameters/subscriptionId"}]}},"/v1/account/subscriptions/{subscriptionId}/payment-method-update-link":{"post":{"operationId":"create_payment_method_update_link","tags":["Billing"],"summary":"Create a payment method update link","description":"Returns a page where the user enters a new card or PayPal account for an `automatic` subscription; for a past due one, the page also collects the overdue payment. Older subscriptions get a Paddle page.","security":[{"bearerAuth":["billing:write"]}],"responses":{"200":{"description":"Payment method update link","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"transactionId":{"type":"string","description":"For Paddle.js `Checkout.open`, to embed the form instead of opening `url`. Omitted for older subscriptions."}},"required":["url"]}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`621`, `622` (`awaiting_payment`, `paid_by_invoicing`, `subscription_canceled`), or a common error; see Errors."}},"parameters":[{"$ref":"#/components/parameters/subscriptionId"}]}},"/v1/account/checkouts":{"post":{"operationId":"create_subscription_checkout","tags":["Billing"],"summary":"Create a subscription checkout","description":"Returns a checkout link for a subscription paid by card or PayPal. Give it to the user, who signs in, accepts the terms and pays; the subscription starts when the payment completes. Calling it again for the same plan returns the same checkout. To pay by bank transfer, use `create_subscription_invoice`.","security":[{"bearerAuth":["billing:write"]}],"responses":{"201":{"description":"Checkout","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"transactionId":{"type":"string","description":"For Paddle.js `Checkout.open`, to embed the checkout instead of opening `url`."}},"required":["url","transactionId"]}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`605`, `613`, `620` (`active_subscription`, `invoice_unpaid`, `payment_overdue`), `623`, `624`, or a common error; see Errors."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPlanChoice"}}}}}},"/v1/account/invoices":{"post":{"operationId":"create_subscription_invoice","tags":["Billing"],"summary":"Create a subscription invoice","description":"Creates a draft invoice for a quarterly or yearly subscription paid by invoicing, with tax from the saved billing details. Nothing is sent or charged until `send_invoice`. Show the user the draft with `get_invoice_pdf`; to correct it, update the billing details and create the draft again, which replaces the earlier one. Invoicing adds `invoicing.historyBonusMonths` of history (`list_plans`).","security":[{"bearerAuth":["billing:write"]}],"responses":{"201":{"description":"Draft invoice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`613`, `620` (`active_subscription`, `invoice_unpaid`, `payment_overdue`), `623`, `624`, `628`, or a common error; see Errors."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPlanChoice"}}}}},"get":{"operationId":"list_invoices","tags":["Billing"],"summary":"List invoices","description":"Newest first, card payments and renewals included; drafts are not listed. Payments of older subscriptions have `type: receipt`: a receipt at `receiptUrl`, without tax details, whose id the invoice operations do not take.","security":[{"bearerAuth":["billing:read"]}],"responses":{"200":{"description":"Invoices and receipts","content":{"application/json":{"schema":{"type":"array","items":{"oneOf":[{"$ref":"#/components/schemas/Invoice"},{"type":"object","properties":{"type":{"const":"receipt"},"id":{"type":"string"},"status":{"const":"paid"},"subscriptionId":{"type":"string"},"name":{"type":"string"},"collectionMode":{"const":"automatic"},"currency":{"type":"string","description":"ISO 4217 code."},"total":{"type":"number"},"paidAt":{"type":"string","format":"date-time"},"receiptUrl":{"type":"string","format":"uri","description":"The link can expire."}},"required":["type","id","status","subscriptionId","name","collectionMode","currency","total","paidAt","receiptUrl"]}]}}}}},"default":{"$ref":"#/components/responses/AccountError"}}}},"/v1/account/invoices/{invoiceId}":{"get":{"operationId":"get_invoice","tags":["Billing"],"summary":"Get an invoice","description":"Also returns drafts.","security":[{"bearerAuth":["billing:read"]}],"responses":{"200":{"description":"Invoice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`625`, or a common error; see Errors."}},"parameters":[{"$ref":"#/components/parameters/invoiceId"}]}},"/v1/account/invoices/{invoiceId}/pdf":{"get":{"operationId":"get_invoice_pdf","tags":["Billing"],"summary":"Get an invoice PDF","description":"The link expires after a few minutes. A draft's PDF is marked as a draft.","security":[{"bearerAuth":["billing:read"]}],"responses":{"200":{"description":"Invoice PDF link","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"}},"required":["url"]}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`625`, or a common error; see Errors."}},"parameters":[{"$ref":"#/components/parameters/invoiceId"}]}},"/v1/account/invoices/{invoiceId}/send":{"post":{"operationId":"send_invoice","tags":["Billing"],"summary":"Send an invoice","description":"Emails the draft with bank transfer details and starts the subscription: data access starts when the payment arrives, and the subscription renews by invoicing until canceled. Until the payment arrives, `cancel_subscription` cancels both, and both end if it is not paid a day after `dueAt`. Sending again returns the invoice unchanged. Agents: confirm the amount and billing details with the user first, and tell them the purchase cannot be refunded once they download or use the data.","security":[{"bearerAuth":["billing:write"]}],"responses":{"200":{"description":"Issued invoice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`613`, `620` (`active_subscription`, `invoice_unpaid`, `payment_overdue`), `625`, or a common error; see Errors."}},"parameters":[{"$ref":"#/components/parameters/invoiceId"}]}},"/v1/account/invoices/{invoiceId}/revise":{"post":{"operationId":"revise_invoice","tags":["Billing"],"summary":"Revise an invoice","description":"Revises a sent or paid invoice with the billing details saved by `update_billing_details`, keeping its number; `get_invoice_pdf` then returns the revised PDF. Only the name, street address and tax ID can change, a tax ID cannot be removed, and a city or region can be added only when the invoice has none. An invoice can be revised once, and not after a refund. A valid VAT number added to a paid invoice refunds its tax; on an unpaid invoice the tax is credited a few seconds later.","security":[{"bearerAuth":["billing:write"]}],"responses":{"200":{"description":"Revised invoice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`625`, `627`, `628`, or a common error; see Errors."}},"parameters":[{"$ref":"#/components/parameters/invoiceId"}]}},"/v1/account/billing-details":{"get":{"operationId":"get_billing_details","tags":["Billing"],"summary":"Get billing details","description":"Before the first purchase or save, only `additionalBillingEmailDomain` is returned; a card purchase sets only `email`.","security":[{"bearerAuth":["billing:read"]}],"responses":{"200":{"description":"Billing details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingDetails"}}}},"default":{"$ref":"#/components/responses/AccountError"}}},"patch":{"operationId":"update_billing_details","tags":["Billing"],"summary":"Update billing details","description":"Omitted fields stay as they are, and null removes an optional field. The first save needs `name`, `countryCode`, `addressLine` and `city`. Subscriptions use the details from their next invoice or receipt; older subscriptions keep the email and address they were bought with. Sent invoices keep their details until `revise_invoice`. A tax ID or address can change the tax of later payments. Fails while a subscription has an overdue payment.","security":[{"bearerAuth":["billing:write"]}],"responses":{"200":{"description":"Billing details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingDetails"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`605`, `622` (`payment_overdue`, `renewal_pending`), or a common error; see Errors."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","minLength":1,"format":"email","description":"Receives invoices and receipts. The current user's login or an address at `additionalBillingEmailDomain`."},"additionalBillingEmails":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Up to 3 more addresses at `additionalBillingEmailDomain` that receive invoices and receipts. Replaces the list."},"name":{"type":"string","minLength":1,"maxLength":200,"description":"Name on invoices and receipts: the person's full name or the company's legal name."},"countryCode":{"type":"string","pattern":"^[A-Za-z]{2}$","description":"Two-letter ISO 3166-1 country code."},"addressLine":{"type":"string","minLength":1,"maxLength":200,"description":"Street address."},"city":{"type":"string","minLength":1,"maxLength":200},"postalCode":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"Required in AU, CA, DE, ES, FR, GB, IN, IT, NL and US."},"region":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"State, province, county or region. Required to pay by invoicing."},"taxId":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"description":"VAT number or other tax ID with its country prefix, for example `DE123456789`."},"companyNumber":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"purchaseOrderNumber":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"description":"Printed on the next invoice from `create_subscription_invoice` and on renewal invoices."}},"required":[]}}}}}},"/v1/account/trials":{"post":{"operationId":"start_trial","tags":["Billing"],"summary":"Start the free trial","description":"One month of free access to data of all supported exchanges from days 1–10 of the previous calendar month (UTC). An account and a user can each have one trial, and an account that has had a subscription has none; `get_account` returns `trialAvailable`.","security":[{"bearerAuth":["billing:write"]}],"responses":{"201":{"description":"Trial data access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DataAccess"}}}},"default":{"$ref":"#/components/responses/AccountError","description":"`613`, `640`, `641`, or a common error; see Errors."}}}},"/v1/exchanges":{"get":{"operationId":"list_exchanges","tags":["Exchanges"],"summary":"List exchanges","description":"Every exchange Tardis.dev records or recorded, with its raw data channels and the period its data covers.","security":[],"responses":{"200":{"description":"Exchanges","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Exchange id for the other calls, for example `binance-futures`."},"name":{"type":"string"},"enabled":{"type":"boolean","description":"`false` while a newly added exchange is not offered yet, before its channels and symbols are verified."},"delisted":{"const":true,"description":"Tardis.dev no longer records the exchange; its data ends at `availableTo`."},"supportsDatasets":{"const":true,"description":"The exchange has CSV files."},"availableSince":{"type":"string","format":"date-time","description":"Inclusive start of the data: the day Tardis.dev started recording the exchange."},"availableTo":{"type":"string","format":"date-time","description":"Exclusive end of the data. Only for delisted exchanges."},"availableChannels":{"type":"array","items":{"type":"string"},"description":"Raw data channels, mostly named as in the exchange API; some, such as order book snapshots, are generated by Tardis.dev."}},"required":["id","name","enabled","supportsDatasets","availableSince","availableChannels"]}}}}},"default":{"$ref":"#/components/responses/AccountError"}}}},"/v1/symbols":{"get":{"operationId":"list_symbols","tags":["Exchanges"],"summary":"List symbols","description":"Finds the symbols with Tardis.dev data of a market, such as BTC/USDT perpetuals, by normalized `baseCurrency` and `quoteCurrency` (at least one is required) on all exchanges or the ones given. Use `id` to replay data and `datasetId` to download CSV files. `availableSince` and `availableTo` bound the data Tardis.dev has for the symbol, not its trading on the exchange: they come from the daily export of that data, so a new symbol appears only after its first day is exported. Lists exchanges alphabetically and, on each, symbols the exchange lists for trading first. When `nextCursor` is returned, more symbols match: narrow the search, or pass it as `cursor`.","security":[],"responses":{"200":{"description":"Symbols","content":{"application/json":{"schema":{"type":"object","properties":{"symbols":{"type":"array","items":{"type":"object","properties":{"exchange":{"type":"string"},"id":{"type":"string","description":"Symbol for replay, real-time streaming and data feeds."},"datasetId":{"type":"string","description":"Symbol for downloading CSV files. It can differ from `id`."},"type":{"enum":["perpetual","future","spot","option","combo","prediction"],"type":"string"},"baseCurrency":{"type":"string"},"quoteCurrency":{"type":"string"},"availableSince":{"type":"string","format":"date-time","description":"Inclusive start of Tardis.dev data for the symbol: its first exported day."},"availableTo":{"type":"string","format":"date-time","description":"Exclusive end of Tardis.dev data for the symbol: the day after its last exported day, or `availableTo` of a delisted exchange. Omitted while Tardis.dev still records it."}},"required":["exchange","id","datasetId","type","availableSince"]}},"nextCursor":{"type":"string","description":"Present when more symbols match."}},"required":["symbols"]}}}},"default":{"$ref":"#/components/responses/AccountError"}},"parameters":[{"name":"exchanges","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated exchange ids from `list_exchanges`, for example `binance-futures,bybit`. All exchanges by default."}},{"name":"baseCurrency","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":150,"description":"Normalized base currency, case-sensitive, for example `BTC`."}},{"name":"quoteCurrency","in":"query","required":false,"schema":{"type":"string","minLength":1,"maxLength":150,"description":"Normalized quote currency, case-sensitive, for example `USDT`."}},{"name":"type","in":"query","required":false,"schema":{"enum":["perpetual","future","spot","option","combo","prediction"],"type":"string"}},{"name":"availableSince","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"description":"Date or timestamp, for example `2024-01-01` or `2024-01-01T12:00:00Z`. Only symbols with data at or after it."}},{"name":"availableTo","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"string","format":"date-time"}],"description":"Date or timestamp. Only symbols with data at it or, with `availableSince`, at any time from `availableSince` to it."}},{"name":"limit","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d+$","description":"From 1 to 1000; 100 by default."}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string","description":"`nextCursor` of the previous page; keep the same filters."}}]}}}}