---
title: "Go-live checklist"
description: "Everything to check before your integration handles real donations, and what changes between the sandbox and live: hosts, credentials, payments and webhooks."
canonical: https://www.charitips.com/docs/get-started/go-live
---

# Go-live checklist

> Everything to check before your integration handles real donations, and what changes between the sandbox and live: hosts, credentials, payments and webhooks.

Your integration works on the sandbox. Go through this list before the first real donation. Nothing you created on the sandbox exists on live: selections, campaigns and webhooks are created again there.

Each item says who can check it: your coding agent with read-only calls to the live API, your coding agent reading your code, or a person. Tick what is done; the prompt at the end of the page hands the rest to your agent.

## Your account

- **The account is validated.** Its onboarding is finished. Until then, creating a token answers `403 Account not active`.
  - id: `account-validated`. Agent check: `GET /v1/accounts/{accountId}` answers `status: VALIDATED`. `GET /v1/accounts` lists the accounts your credentials can read, so you do not need the id in advance. Calls: `get-account`, `list-accounts`.
- **The live account has an active subscription.** Without one, activating a campaign answers `402 NO_ACTIVE_SUBSCRIPTION`. See [Plans and prerequisites](https://www.charitips.com/docs/overview/plans.md).
  - id: `subscription`. Manual: In the dashboard billing settings. `GET /v1/accounts/{accountId}?includeBillingInfo=true` shows the plan in `billingInfo.plan` and the next billing date in `billingInfo.nextBillingAt`, not whether the subscription is active. Calls: `get-account`.
- **A payment method is on the account that pays.** That is your account or on each child account if donations must be billed by Charitips directly to your business customers. Without one, donations answer `402 Missing payment method`.
  - id: `payment-method`. Agent check: `GET /v1/accounts/{accountId}/payment-methods` on the paying account lists at least one method with `status: ENABLED`. Calls: `get-payment-methods`.
- **Your plan has the features your flow uses.** API access for webhooks, the B2C use case when your users pay, the account hierarchy feature for child accounts. A missing one answers `402 Plan upgrade required`, or `403` for the B2C settings. See [Plans and prerequisites](https://www.charitips.com/docs/overview/plans.md).
  - id: `plan-features`. Agent check: `GET /v1/accounts/{accountId}/entitlements` answers `true` for each feature your flow uses, against the flow-by-flow list of Plans and prerequisites: `apiAccess` for webhooks, `b2c` when your users pay, `accountHierarchy` for child accounts. Calls: `get-entitlements`.

## Credentials and hosts

- **Live credentials are in your server's secrets.** Live client ids and secrets start with `live_`. They never go in a web page, a mobile app or a repository.
  - id: `live-credentials`. Code review: The values of `CHARITIPS_CLIENT_ID` and `CHARITIPS_CLIENT_SECRET` in the live environment start with `live_`, checked without printing them; no `live_` or `test_` value appears in the repository, a web bundle or a mobile app.
- **Every call goes to `api.charitips.com`, and every widget to `embed.charitips.com`.** A `live_` pair sent to the sandbox, or a `test_` pair sent to live, answers `401 Invalid credentials`.
  - id: `live-hosts`. Agent check: The live configuration names `api.charitips.com` and `embed.charitips.com` and no `sandbox.` host. `POST /v1/authentication` on `https://api.charitips.com` with the live pair answers `200` with an `accessToken`. Calls: `create-token`.
- **One token is reused for an hour.** Create a token, keep it in memory or a shared cache, and create the next one when a call answers `401`. The token endpoint is meant to be called once an hour, not before each call. See [Authentication](https://www.charitips.com/docs/get-started/authentication.md).
  - id: `token-reuse`. Code review: The code caches the token and calls `POST /v1/authentication` once an hour, or once after a `401`, never before each call.

## Campaigns

- **The live charities selection and campaigns exist, and are active.** Activation needs a selection with at least one charity. Store the live ids in your configuration, apart from the sandbox ones.
  - id: `live-campaigns`. Agent check: `GET /v1/charities-selections?includeCharities=true` returns each selection id of the live configuration with at least one charity; `GET /v1/campaigns` returns each campaign id of the live configuration with `status: ACTIVE`. Calls: `list-charities-selections`, `list-campaigns`.
- **Fixed budgets are paid.** A campaign with a fixed budget is usually invoiced when you activate it, and opens once the invoice is paid. A budget above what your card or SEPA direct debit can be charged at once is refused, on live only.
  - id: `fixed-budget-paid`. Agent check: A campaign with `amountType: FIXED_AMOUNT` reads `status: ACTIVE` once its invoice is paid; one still `PENDING` after activation is waiting for payment. Calls: `get-campaign`.
- **Receipts are set the way you want.** Each campaign issues receipts once a year (the default) or when it closes (`fiscalReceiptType`). When your users pay, send their name and postal address, or `withFiscalReceipt: false` when they decline a receipt, and offer charities that issue receipts. See [Billing and fiscal receipts](https://www.charitips.com/docs/concepts/billing-and-receipts.md).
  - id: `receipts`. Agent check: `fiscalReceiptType` on each live campaign is the one you want. When your users pay, `GET /v1/charities-selections?includeCharities=true` shows `fiscalReceiptsSupport: ENABLED` on each charity they can pick. Calls: `get-campaign`, `list-charities-selections`.

## Calls

- **Every create sends a `uniqueExternalId`.** Donations, votes, donors and recurring donations. A retried call then answers `409` instead of creating a duplicate.
  - id: `unique-external-id`. Code review: Every `POST /v1/donations`, `/v1/votes`, `/v1/donors` and `/v1/recurring-donations` body carries `uniqueExternalId`, set to your own id for the event, and a `409` is handled as a success.
- **Donations are created from your server.** After the event that triggers them (a paid order, a validated referral), not from the browser.
  - id: `server-side`. Code review: No call to `api.charitips.com` and no credential in browser or mobile code; the create call runs after the event is confirmed.
- **Errors are handled by status.** `402`: a plan feature or a payment method is missing, alert your team. `403`: the state of the resource refuses the call, do not retry. `409`: the resource already exists or is no longer pending, read it. `429`: wait for `Retry-After`. See [Errors](https://www.charitips.com/docs/api-reference/errors.md), [Troubleshooting](https://www.charitips.com/docs/api-reference/troubleshooting.md).
  - id: `errors-by-status`. Code review: The error handling branches on the HTTP status as described; only a `401` with a new token, a `429` after `Retry-After` and a `500` are retried, once.

## Webhooks

- **Webhooks are created on live, with the events you listen to.** A sandbox webhook only receives sandbox events.
  - id: `live-webhooks`. Agent check: `GET /v1/webhooks` on live returns a webhook whose `target` is your live endpoint, with every event your code handles in `events`. Calls: `list-webhooks`.
- **The signature is checked with the live `signingKey`.** It is shown once, when the webhook is created: store it then. Check it on the raw body, before parsing it. See [Webhooks configuration](https://www.charitips.com/docs/webhooks/configuration.md).
  - id: `signature`. Code review: The handler verifies `X-Charitips-Signature` on the raw body with the live signing key, as in Webhooks configuration, and refuses a bad signature with a status Charitips does not retry.
- **Handlers are idempotent.** Events are delivered at least once, and internal updates send events too.
  - id: `idempotent-handlers`. Code review: The handler keys its effects on the resource id and its status, so a second delivery changes nothing.
- **Your endpoint answers `2xx` once it has stored the event.** Charitips retries only after `429`, `500`, `502`, `503` or `504`; any other error status is not retried. See [Webhooks configuration](https://www.charitips.com/docs/webhooks/configuration.md).
  - id: `answer-2xx`. Code review: The handler stores the event, then answers `2xx`; it answers `5xx` only when the event could not be stored.

## Business customers, if you have them

- **Child accounts are created on live.** Each with its legal registration number and postal address in its fiscal info, which fiscal receipts need.
  - id: `child-accounts`. Agent check: `GET /v1/accounts/{accountId}/child-accounts` returns each customer with `status: VALIDATED`; `GET /v1/accounts/{childAccountId}?includeFiscalInfo=true` on each one returns a `fiscalInfo` with `legalRegistrationNumber`, `street`, `zip`, `city` and `country`. Calls: `list-child-accounts`, `get-account`.
- **The billing mode is chosen.** For business customers, you can be invoiced for all of them, or each one is invoiced directly by Charitips. See [Account hierarchy](https://www.charitips.com/docs/concepts/account-hierarchy.md), [Bill your business customers](https://www.charitips.com/docs/guides/account-hierarchy-billing.md).
  - id: `billing-mode`. Manual: A decision for your team, taken when each child account is created. `billingInfo.billedTo` on a child account reads `ACCOUNT` when the customer is invoiced directly, `PARENT_ACCOUNT` when you are. Calls: `list-child-accounts`.

## Let your agent check this

Copy this prompt into your coding agent. It reads this page as Markdown, runs the read-only calls of the agent checks with your live credentials, reads your code for the code reviews, and lists the manual items for you. The items you have ticked are left out.

```prompt
Read https://www.charitips.com/docs/get-started/go-live.md and check my integration against its go-live checklist. Use the live credentials from the environment variables CHARITIPS_CLIENT_ID and CHARITIPS_CLIENT_SECRET against https://api.charitips.com: create one token with POST /v1/authentication, then run only the GET calls the agent checks name. Never create, update or delete anything else, and never print a credential or a token. For the code reviews, read my code. For the manual items, tell me what to confirm and where. Report item by item, with its id: passed, failed with the reason, or manual.
```

The docs MCP server cannot run these calls: it is read-only and has no API key. The agent uses your credentials from its environment.

## Sandbox or live

What changes between the two environments:

- **API host**: `api.sandbox.charitips.com` on the sandbox, `api.charitips.com` on live.
- **Widgets**: `embed.sandbox.charitips.com` on the sandbox, `embed.charitips.com` on live.
- **Credentials**: start with `test_` on the sandbox, with `live_` on live. Each pair only works on its own environment.
- **Payments**: a test card and a test SEPA account on the sandbox, given on the [Sandbox](https://www.charitips.com/docs/get-started/sandbox.md) page; real money on live.
- **Payment method checks**: donations skip them on the sandbox; on live, the paying account needs a payment method.
- **Card and SEPA amount limits**: never applied on the sandbox; a fixed budget above the limit is refused on live.
- **Subscription**: needed on both to activate a campaign.
- **Data**: separate. An id from the sandbox does not exist on live, and answers `404` or `400`.
