---
title: "Create a recurring donation"
description: "This recurring donation will then have to be claimed i.e linked to a Charity by the donor."
canonical: https://www.charitips.com/docs/api-reference/create-recurring-donation
---

# Create a recurring donation

`POST /v1/recurring-donations`

This recurring donation will then have to be claimed i.e linked to a Charity by the donor.

**Authentication**: Bearer access token.

## Body

- `campaignId` (string, required, UUID): Id of the campaign
- `amount` (integer (int64), required, minimum 1): Donation amount in minor currency unit i.e cents.
- `donorFirstName` (string, required): First name of the donor. Will be used for email communications.
- `donorLastName` (string, required): Last name of the donor. Will be used for email communications.
- `donorEmail` (string, required): Email of the donor. Will be used for email communications.
- `externalId` (string): An optional internal id of your system e.g orderId or customerId. Can be used to link a recurring donation to an entity in your system.
- `uniqueExternalId` (string): Similar to externalId but should be unique across all recurring donations. Can be used to prevent duplicate recurring donations.
- `language` (string): Locale to be used to communicate with the donor. Default to the campaign's language value. One of `fr`, `en`.

## Response 201

- `recurringDonationId` (string, required)
- `type` (RecurringDonationType, required) One of `FREQUENCY`, `MANUAL`.
- `amountType` (RecurringDonationAmountType, required) One of `FIXED_AMOUNT`, `RATE`.
- `status` (RecurringDonationStatus, required) One of `PENDING`, `ACTIVE`, `PAUSED`, `CANCELED`.
- `hasBeenCharged` (boolean, required)
- `feeType` (FeeType, required) One of `EXCLUDED`, `INCLUDED`.
- `amount` (integer (int64), required)
- `rate` (number)
- `baseAmount` (integer (int64))
- `withRounding` (boolean, required)
- `frequency` (string)
- `secret` (string, required)
- `externalId` (string)
- `uniqueExternalId` (string)
- `sendingMode` (CampaignSendingMode, required) One of `MANUAL`, `EMAIL`, `PHYSICAL`, `SLACK`, `POSTAL`.
- `sendingDate` (string (date-time))
- `sendingStatus` (DonationSendingStatus, required) One of `PENDING`, `FAILED`, `DONE`.
- `lastReminderId` (string)
- `message` (string)
- `reminderMessage` (string)
- `from` (string)
- `language` (Language, required) One of `fr`, `en`.
- `accountId` (string, required)
- `campaignId` (string, required)
- `charityId` (string)
- `donorId` (string, required)
- `createdAt` (string (date-time), required)
- `updatedAt` (string (date-time), required)

## Errors

- 400 `Recurring donations can only be created for FREE_AMOUNT campaigns`: Use a campaign with amountType FREE_AMOUNT for recurring donations. See https://www.charitips.com/docs/api-reference/create-campaign.md.
- 400 `A field is missing, has the wrong type, or is not part of the request schema.`: `message` lists every problem. Unknown fields are rejected, not ignored: remove them rather than sending extra data. See https://www.charitips.com/docs/api-reference/errors.md.
- 400 `Bad Request`: The `campaignId` does not exist on your account and environment. Ids from the sandbox do not exist in production. See https://www.charitips.com/docs/api-reference/errors.md.
- 401 `Unauthorized`: The access token is missing, expired or invalid. Create a new one with your client id and secret, send it as `Authorization: Bearer <accessToken>`, then retry once. Sandbox tokens only work on api.sandbox.charitips.com. See https://www.charitips.com/docs/get-started/authentication.md.
- 402 `Missing payment method`: The account that pays for the donations (your (parent) account or a child account if they are billed directly) has no payment method. Add one in the dashboard, under Settings > Billing, then retry. On the sandbox, creating a single donation skips this check, but other calls can still return it, like activating a FIXED_AMOUNT campaign that is billed on order. See https://www.charitips.com/docs/concepts/billing-and-receipts.md#payment-methods.
- 403 `Campaign has ended.`: The campaign is COMPLETE or CANCELED: nothing can be created, claimed or cast on it any more. Use an active campaign. See https://www.charitips.com/docs/api-reference/list-campaigns.md.
- 403 `Recurring donations can only be created for recurring frequency campaigns.`: Recurring donations need a campaign whose `recurringType` is `FREQUENCY`. Read the campaign to check it. `recurringType` cannot be set when you create a campaign: it comes from the campaign template. See https://www.charitips.com/docs/use-cases/recurring-donations.md.
- 403 `Campaign has to be activated first.`: Activate the campaign once it has its charities selection, then retry. See https://www.charitips.com/docs/api-reference/activate-campaign.md.
- 403 `Account not validated`: The account behind your credentials has not finished onboarding. Complete it in the dashboard, or contact us. See https://www.charitips.com/docs/api-reference/troubleshooting.md#calls-answer-403-account-not-active-account-not-validated-or-account-closed.
- 403 `Account closed`: The account behind these credentials is closed: no token is issued and every call is refused, reads included. Contact Charitips to reopen it. See https://www.charitips.com/docs/api-reference/troubleshooting.md#calls-answer-403-account-not-active-account-not-validated-or-account-closed.
- 409 `Unique constraint failed on uniqueExternalId`: A resource with this uniqueExternalId already exists: your previous call succeeded. Fetch it with the list endpoint filtered by uniqueExternalId (donations, votes, donors) instead of creating it again; for recurring donations, keep the id you received at creation. See https://www.charitips.com/docs/api-reference/list-donations.md.

## Example

```bash
curl -X POST https://api.sandbox.charitips.com/v1/recurring-donations \
  -H "Authorization: Bearer $CHARITIPS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "campaignId": "<campaignId>",
    "amount": 2000,
    "donorFirstName": "Jane",
    "donorLastName": "Doe",
    "donorEmail": "jane.doe@example.com",
    "uniqueExternalId": "subscription_2291"
  }'
```

```javascript
const response = await fetch('https://api.sandbox.charitips.com/v1/recurring-donations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHARITIPS_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "campaignId": "<campaignId>",
    "amount": 2000,
    "donorFirstName": "Jane",
    "donorLastName": "Doe",
    "donorEmail": "jane.doe@example.com",
    "uniqueExternalId": "subscription_2291"
  }),
});
if (!response.ok) throw new Error(`${response.status} ${await response.text()}`);
const data = await response.json();
```

```python
import os, requests

response = requests.post(
    "https://api.sandbox.charitips.com/v1/recurring-donations",
    headers={"Authorization": f"Bearer {os.environ['CHARITIPS_TOKEN']}"},
    json={
      "campaignId": "<campaignId>",
      "amount": 2000,
      "donorFirstName": "Jane",
      "donorLastName": "Doe",
      "donorEmail": "jane.doe@example.com",
      "uniqueExternalId": "subscription_2291"
    },
)
response.raise_for_status()
data = response.json()
```

## Response example (201, placeholder values)

```json
{
  "recurringDonationId": "<recurringDonationId>",
  "type": "FREQUENCY",
  "amountType": "FIXED_AMOUNT",
  "status": "PENDING",
  "hasBeenCharged": false,
  "feeType": "EXCLUDED",
  "amount": 2000,
  "rate": 1
}
```
