Creates a new credit bundle or plan for an environment
POST /api/configuration/credits
- Products: Gladstone Admin Areas (
ADMIN) - Features: not restricted by feature
Overview
Grants an environment a pool of email and SMS credits, which are then drawn down as messages are sent. planId decides which of two quite different things happens:
planIdabove 0 — a recurring plan. The plan is recorded as the environment's active plan, and its credits are added to the environment. An environment may hold only one active recurring plan; a second attempt is rejected with400.planIdof 0, or omitted — a one-off bundle. No active plan is recorded; the credits are simply added to the environment. Because no plan is recorded, one-off bundles do not collide with each other or with a recurring plan, and you can add as many as you like.
Valid planId values come from GET /api/configuration/default-communication-plans; what an environment currently holds comes from GET /api/configuration/communication-plans/{environmentId}.
A successful call returns 200 OK with an empty body — not 201, and with no identifier for what it created. The credits are applied asynchronously after the response has been sent, so a 200 means "accepted", not "the balance has changed". Read the balance back from GET /api/configuration/communication-plans/{environmentId}.
Validation runs in a fixed order — environment, then dates, then plan and credits, then the active-plan check — and stops at the first failure, so fix the errors in that order.
Endpoint
POST {base_url}/api/configuration/credits
{base_url} is the environment URL issued to your integration. See Authenticating with Gladstone APIs.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
id | integer (int32) | No | Ignored on create. The field exists because PUT /api/configuration/credits takes the same body, where it identifies the plan being amended. Whatever you send here is discarded, and the id assigned is not returned. |
tenantId | string | Yes | The tenant that owns the environment, as a GUID. It is trimmed before use, and must parse as a GUID — anything else is rejected with TenantId '{value}' is not a valid GUID. and a blank or whitespace-only value with TenantId was unexpectedly blank or null. Omitting the field entirely, or sending null, is worse than sending a blank string: you get a 500 rather than a 400. Maximum 40 characters. |
environmentId | integer (int32) | Yes | The environment the credits are granted to. Must be above 0 (EnvironmentId must be an integer above 0.) and must already exist (EnvironmentId {id} does not exist.). |
planId | integer (int32) | No | Which default communication plan this grant is based on. Take the value from GET /api/configuration/default-communication-plans; a value that does not match one is rejected with PlanId {id} does not exist. and a negative value with PlanId must be a positive integer. Send 0, or omit the field, to create a one-off bundle instead of a recurring plan — the field is not nullable, so omitting it is the same as sending 0. Any value above 0 is treated as a recurring plan and is subject to the one-active-plan-per-environment rule. |
isActive | boolean | No | Ignored on create. The plan is always created as active regardless of what you send. To retire a plan, use PUT /api/configuration/credits. |
includedEmails | integer (int32) | No | The number of email credits this grant adds. Omit it, or send null, to grant no email credits — but at least one of includedEmails and includedSMS must be 1 or more, or the request is rejected with Plan cannot include 0 credits. At least 1 credit must be included for Email or SMS. A negative value in only one of the two fields is currently accepted rather than rejected, so validate signs yourself. |
includedSMS | integer (int32) | No | The number of SMS credits this grant adds. Behaves exactly as includedEmails, and is subject to the same combined rule and the same acceptance of a negative value — the pair is only rejected when both values are absent or 0 or below. |
startDate | string (date-time) | Yes | When the credits become available. It must be supplied (StartDate must be specified and cannot be blank.) even though the field is nullable. Only the date part is kept; the time is discarded. A start date in the past is accepted. |
expiryDate | string (date-time) | No | When the credits lapse. Only the date part is kept. It must not be earlier than today (ExpiryDate cannot be in the past.) nor earlier than startDate (ExpiryDate cannot be before the StartDate.). Omit it, or send null, and it defaults to startDate plus 12 months — it does not mean "never expires". |
Sample request
curl -X POST '{base_url}/api/configuration/credits' \
-H 'Authorization: Bearer {accessToken}' \
-H 'X-Use-SSO: true' \
-H 'Content-Type: application/json' \
-d '{
"id": 12345,
"tenantId": "string",
"environmentId": 12345,
"planId": 12345,
"isActive": true,
"includedEmails": 1,
"includedSMS": 1,
"startDate": "2026-08-14T19:00:00Z",
"expiryDate": "2026-08-14T19:00:00Z"
}'Errors
| Status | Meaning | When |
|---|---|---|
400 | Bad request | The environment is wrong: EnvironmentId must be an integer above 0. for a value of 0 or below, or EnvironmentId {id} does not exist. when no such environment is registered. |
400 | Bad request | tenantId is blank or whitespace (TenantId was unexpectedly blank or null.), or is not a GUID (TenantId '{value}' is not a valid GUID.). |
400 | Bad request | The dates do not hang together: StartDate must be specified and cannot be blank., ExpiryDate cannot be in the past., or ExpiryDate cannot be before the StartDate. |
400 | Bad request | planId is negative (PlanId must be a positive integer.) or names a default plan that does not exist (PlanId {id} does not exist.). |
400 | Bad request | Neither includedEmails nor includedSMS carries a positive value — Plan cannot include 0 credits. At least 1 credit must be included for Email or SMS. |
400 | Bad request | You sent a recurring plan (planId above 0) for an environment that already holds one — EnvironmentId {id} already has an active credit plan. One-off bundles (planId of 0) are not subject to this rule and remain accepted. |
400 | Bad request | The whole body was sent as null — Add credits request cannot be null. |
500 | Internal server error | tenantId was omitted or sent as null. A missing field fails with an unexpected server-side error rather than the 400 you would expect. Send an empty string if you want the validation message instead. |
500 | Internal server error | The environment could not be resolved when applying the credits, or the credits could not be queued for processing. For a recurring plan the active plan may already have been recorded before this point, so re-check with GET /api/configuration/communication-plans/{environmentId} before retrying. |