Send Code to Participant
Send an assigned code to the participant who holds it, by email, SMS or both.
https://api-v3.sweeppea.com/codes/send
Description
This endpoint is the API twin of the "Send code" action in the Sweeppea app. There is no address field: the code goes to the participant it is assigned to, at the email address and/or phone number they registered with, and only when it is that participant's current code.
Nothing is sent from this endpoint. The message is queued and the Messaging Engine writes it in the sweepstakes' language and delivers it within about a minute, re-checking suppressions, the monthly allowance, sending pauses and, for SMS, the 10DLC number and quiet hours (an SMS during quiet hours is deferred, never dropped).
403 with Data.Code: "DirectMessageNotEnabled" — contact Sweeppea support. There is no fallback path around the engine.
Authentication
This endpoint requires Bearer token authentication via the Authorization header. Because it changes data, the Codes & Coupons module must also be enabled for your account.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
CouponToken |
String | Yes | UUID v4 of a code assigned to a participant |
Channel |
String | Yes | email, sms or both. both sends on each channel the participant has a usable address for |
IdempotencyKey |
String | No | 8 to 64 characters [A-Za-z0-9_-]. Retrying with the same key never sends twice |
Code Examples
curl -X POST "https://api-v3.sweeppea.com/codes/send" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"CouponToken": "uuid-v4-string",
"Channel": "both",
"IdempotencyKey": "pos-send-000913"
}'
const response = await fetch('https://api-v3.sweeppea.com/codes/send', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
CouponToken: "uuid-v4-string",
Channel: "both",
IdempotencyKey: "pos-send-000913"
})
});
const data = await response.json();
console.log(data);
import requests
url = "https://api-v3.sweeppea.com/codes/send"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"CouponToken": "uuid-v4-string",
"Channel": "both",
"IdempotencyKey": "pos-send-000913"
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())
Response
{
"Response": true,
"Telemetry": {
"DataConsumed": 0,
"APICalls": 312,
"MaxAPICalls": 1500000
},
"Data": {
"CouponToken": "uuid-v4-string",
"ParticipantToken": "uuid-v4-string",
"Duplicate": false,
"Channels": [
{
"Channel": "email",
"Status": "queued",
"MessageToken": "uuid-v4-string"
},
{
"Channel": "sms",
"Status": "skipped",
"Reason": "NoAddress",
"Message": "The participant has no valid phone number."
}
]
},
"Message": "Code queued. It is delivered within about a minute (SMS outside quiet hours)."
}
{
"Response": true,
"Telemetry": {
"DataConsumed": 0,
"APICalls": 312,
"MaxAPICalls": 1500000
},
"Data": {
"CouponToken": "uuid-v4-string",
"Duplicate": true,
"Channels": [
{
"Channel": "email",
"Status": "delivered",
"MessageToken": "uuid-v4-string"
}
]
},
"Message": "This code was already queued with the same IdempotencyKey. Nothing new was sent."
}
Response Fields
| Field | Type | Description |
|---|---|---|
CouponToken |
String | The code |
ParticipantToken |
String | The participant it was queued to (absent on a duplicate) |
Duplicate |
Boolean | true when the same IdempotencyKey was already used for this code — nothing new was sent |
Channels[].Status |
String | queued for a new message (on a duplicate, the current delivery status), or skipped |
Channels[].MessageToken |
String | Id of the queued message |
Channels[].Reason / Message |
String | Why a channel was skipped: NoAddress, UnsupportedCountry, Suppressed, RecipientDailyLimit, AllowanceExhausted |
Error Responses
{
"Response": false,
"Message": "Missing required parameter: Channel",
"Code": 400,
"Help": {
"ExpectedBody": {
"CouponToken": "string (required) — UUID v4 of a code assigned to a participant",
"Channel": "string (required) — email | sms | both",
"IdempotencyKey": "string (optional) — 8 to 64 characters [A-Za-z0-9_-]. Retrying with the same key never sends twice",
"CalledFromMCP": "boolean (optional) — Set by the MCP server, ignore it",
"CalledFromCLI": "boolean (optional) — Set by the CLI, ignore it"
}
}
}
{
"Response": false,
"Message": "Sending codes through the API is not enabled for your account yet. Contact Sweeppea support to enable it.",
"Code": 403,
"Data": {
"Code": "DirectMessageNotEnabled"
}
}
{
"Response": false,
"Message": "Code not found. It must exist and belong to your account.",
"Code": 404
}
{
"Response": false,
"Message": "This code is not assigned to any participant. Assign it first with /codes/assign.",
"Code": 409,
"Data": {
"Code": "NotAssigned"
}
}
{
"Response": false,
"Message": "This is not the participant's current code, so it cannot be sent (the message always carries the participant's current code).",
"Code": 409,
"Data": {
"Code": "NotCurrentCode"
}
}
{
"Response": false,
"Message": "Nothing was sent. See Data.Channels for the reason on each channel.",
"Code": 422,
"Data": {
"Channels": [
{
"Channel": "email",
"Status": "skipped",
"Reason": "Suppressed",
"Message": "This address is on the suppression list."
}
]
}
}
{
"Response": false,
"Message": "Daily limit reached: at most 200 code messages per 24 hours through the API.",
"Code": 429,
"Data": {
"Code": "AccountDailyLimit",
"Limit": 200
}
}
{
"Response": false,
"Message": "Missing or invalid Bearer token. Send your API token in the Authorization header as: Authorization: Bearer YOUR_API_TOKEN",
"Code": 401
}
{
"Response": false,
"Message": "Invalid API token. It does not match any account.",
"Code": 403
}
{
"Response": false,
"Message": "The Codes & Coupons module is not enabled for your account. Contact support to enable it.",
"Code": 403
}
{
"Response": false,
"Message": "Rate limit exceeded. Your plan allows 60 API calls per minute. Wait a few seconds and try again.",
"Code": 429
}
{
"Response": false,
"Message": "Internal server error. Please try again; if it persists, contact support with the time of this request.",
"Code": 500
}
Every 400 carries a Help.ExpectedBody block listing every accepted parameter. A disabled or hibernating account and an exhausted monthly API quota answer 403; the per-minute limit answers 429 — see Concurrency & Rate Limiting.
Important Notes
- Requires the Codes & Coupons module on the account and the Messaging Engine rollout (
403otherwise). - The message text is written by the Messaging Engine from the sweepstakes' own settings, in the sweepstakes' language — the API does not take a message.
- Codes are sent as transactional messages: they count against the channel's monthly allowance and may use it up to its 120% transactional ceiling.
IdempotencyKeyis scoped to the code, participant and channel; a retry with the same key returnsDuplicate: trueand does not count toward the daily ceiling.- With
Channel: "both", channels without a usable address are reported asskippedwhile the others are still queued. - Writes an entry to the account log at level 3, prefixed
[ API v3 ]. - Every
200response carriesTelemetrywith your API calls this month (APICalls) and the plan maximum (MaxAPICalls). - Purging all the codes of a sweepstakes, removing duplicates and importing codes from a CSV file stay in the Sweeppea app. Every write endpoint of this category requires the Codes & Coupons module; reads do not.