API Documentation
frankk. APIs let users connect their apps with frankk. in a safe and simple way.
They help users manage recipients, create campaigns, work with files, and check account details using clear JSON requests and responses.
frankk. starts authentication with an API key.
Send your API key to POST /api/v1/account/login. If valid, the API returns:
- token (short-lived access token)
- refreshToken (longer-lived token)
- refreshExpiry
Use the access token in the Authorization header as Bearer <token> for protected endpoints.
When the access token expires, call POST /api/v1/account/refresh with the current refreshToken. If the refresh token is valid, the API revokes the old refresh token and issues a new access token plus a new refresh token (token rotation). If the refresh token is invalid or expired, the API returns 401 Unauthorized.
Refresh tokens expire 7 days after issuance.
Any frankk. user can generate an API key from Settings > API Settings by selecting Generate.
However, API access can only be used after an administrator enables API permissions for that user account.
Once generated, the API key should be stored securely, as it is required for authentication and may only be shown once in full.
If needed, the user can select Rotate to issue a new key, which immediately revokes the previous key.
API Logging lets you track how your integration calls frankk., so you can monitor usage and fix issues quickly.
What you can do
- Enable logging for your company
- Set logging duration and extend it when needed
- Disable logging at any time
- View API logs list and open log details
- Filter logs by date, method, status code, and endpoint
What each log shows
- Which endpoint was called and with which method
- When the request happened and how long it took
- Which status code was returned
- Request/response information needed for troubleshooting
Business value
- Detect and resolve integration issues faster
- Validate API usage during onboarding and go-live
- Monitor failed calls and improve reliability
- Support operational reviews and audit checks
Headers and content
Include x-api-key where required by authentication flow. For secured endpoints, send Authorization: Bearer {access-token}. Use Content-Type: application/json for JSON requests and multipart/form-data for file uploads.
Rate limits
API requests are rate-limited per configured policy. If the threshold is exceeded, the API returns 429 Too Many Requests. Clients should retry with backoff.
Response and pagination
Standard responses use ApiResponse<T> with Success, Message, Data, and Errors. List endpoints typically return pagination metadata via PagedResult<T> fields such as Total, Offset, Limit, HasMore, and NextOffset.
Date, time, and file constraints
Date/time values are returned in API-defined string format and should be parsed by clients as date-time values. File endpoints support JSON/base64 and multipart upload patterns.
Base URL and versioning
All endpoints in this document are versioned under https://app.frankk.post/api/v1. Example: POST https://app.frankk.post/api/v1/account/login.
frankk. API provides a secure and structured way to integrate with authentication, recipients, recipient groups, campaigns, templates, files, and account services.
All endpoints return standard HTTP status codes so integrations can clearly identify success, client-side issues, and server-side failures.
Note
Some business-rule outcomes may return 200 OK with a message in the response body, so always check response content (Success, Message, Errors) along with the HTTP status.
Request completed successfully.
Request accepted for background/asynchronous processing.
Invalid input, missing fields, wrong format, or failed validation.
Missing, invalid, or expired authentication credentials (API key, access token, or refresh token).
Authenticated, but not allowed to access this resource/action.
Requested resource does not exist.
Request conflicts with current resource state.
Request body or file is too large.
Rate limit exceeded.
Unexpected server-side error.
POST /api/v1/account/login is the authentication entry point for your integration. It accepts an API key in the request body and, on success, returns a JWT access token plus a refresh token. Use the returned Token as Authorization: Bearer <token> when calling protected endpoints. This endpoint is typically the first call in your workflow before actions like checking balance, creating campaigns, or managing recipients.
ApiKey
API key generated in Frankk API Settings; used to authenticate login request.
successful login
invalid or expired API key
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/account/login” -H “Content-Type: application/json” -d “{\”ApiKey\”:\”sk_live_example_key\”}”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/account/login” -H “Content-Type: application/json” -d ‘{“ApiKey”:”sk_live_example_key”}’
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/account/login” -H “Content-Type: application/json” -d ‘{“ApiKey”:”sk_live_example_key”}’
JSON Request Body:
{
"ApiKey": "sk_live_example_key"
}
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Login successful",
"data": {
"token": "jwt-access-token",
"expiry": "2026-02-24T12:02:34.9104432Z",
"refreshExpiry": "2026-03-03T11:47:34.9106126Z",
"refreshToken": "refresh-token"
},
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Invalid or expired API key",
"data": null,
"errors": ["Unauthorized"]
}
Request Schema: LoginRequest { apiKey: string }
Response Schema: ApiResponse<JwtResponse>
Response DTO: JwtResponse { token, expiry, refreshToken, refreshExpiry }
POST /api/v1/account/refresh renews authentication tokens for an active API session. It accepts a refresh token and, on success, returns a new JWT access token together with a newly rotated refresh token. Use this endpoint when the current access token is expired or close to expiry.
RefreshToken
Unexpired refresh token issued by the login or previous refresh response (current validity window: 7 days from issuance).
Token refreshed successfully and new token pair returned.
Refresh token is invalid or expired.
Request
cURL Request (Example):
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/account/refresh” -H “Content-Type: application/json” -d “{\”RefreshToken\”:\”existing-refresh-token\”}”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/account/refresh” -H “Content-Type: application/json” -d ‘{“RefreshToken”:”existing-refresh-token”}’
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/account/refresh” -H “Content-Type: application/json” -d ‘{“RefreshToken”:”existing-refresh-token”}’
JSON Request Body:
{
"RefreshToken": "existing-refresh-token"
}
Copied!
Response
cURL Response (Example):
HTTP/1.1 200 OK
{
"success": true,
"message": "Token refreshed successfully",
"data": {
"token": "new-jwt-access-token",
"expiry": "2026-02-26T12:02:34.9104432Z",
"refreshExpiry": "2026-03-05T11:47:34.9106126Z",
"refreshToken": "new-refresh-token"
},
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Invalid or expired refresh token",
"data": null,
"errors": [
"Unauthorized"
]
}
Request Schema: RefreshRequest { refreshToken: string }
Response Schema: ApiResponse<JwtResponse>
Response DTO: JwtResponse { token, expiry, refreshToken, refreshExpiry }
POST /api/v1/account/balance returns the current account balance for the authenticated company. Use this endpoint to check available funds before creating or scheduling campaigns.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
Balance retrieved successfully.
Missing or invalid authentication token, or CompanyId claim not available.
Authenticated token is valid, but the account does not have permission to access balance.
Unexpected error while retrieving company balance.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/account/balance” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/account/balance” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/account/balance” -H “Authorization: Bearer <access-token>”
JSON Request Body:
No request body is required.
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Successful!",
"data": {
"CurrencyCode": "GBP",
"Balance": 1500.25
},
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": [
"Unauthorized"
]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": [
"Forbidden"
]
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": [
"Internal server error"
]
}
Request Schema: None (Authorization header required)
Response Schema: ApiResponse<object>
Response DTO: object { CurrencyCode, Balance }
GET /api/v1/files/folders/contents returns the files and subfolders under a selected folder path in the company library. Use this endpoint to load folder views in file-management flows.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
path
Relative folder path under Home. If omitted, the endpoint resolves to the default Home folder.
sort
Sort mode for contents. Allowed values: name, date. Default is name. Any value other than date is treated as name.
Folder contents returned successfully.
Invalid path input or unexpected path validation failure.
Missing or invalid authentication token.
Authenticated token is valid, but access is denied by policy or path guard.
Request
cURL Request Example:
Windows cmd:
curl -X GET “{{baseUrl}}/api/v1/files/folders/contents?path=Home/Assets&sort=name” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X GET “{{baseUrl}}/api/v1/files/folders/contents?path=Home/Assets&sort=name” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X GET “{{baseUrl}}/api/v1/files/folders/contents?path=Home/Assets&sort=name” -H “Authorization: Bearer <access-token>”
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Folder contents",
"data": {
"files": [
{
"fileName": "brochure.pdf",
"relativePath": "Home/Assets/brochure.pdf",
"extension": ".pdf",
"sizeInBytes": 245760,
"sizeInMB": 0.234375,
"creationDate": "2026-02-26T10:12:00Z",
"lastModified": "2026-02-26T10:15:00Z"
}
],
"folders": [
{
"folderName": "Archive",
"relativePath": "Home/Assets/Archive",
"creationDate": "2026-01-20T09:00:00Z",
"sizeInBytes": 1048576,
"sizeInMB": 1.0
}
]
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Invalid path.",
"data": null,
"errors": ["Invalid path input"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Unauthorized access.",
"data": null,
"errors": ["Forbidden"]
}
Request Schema: None (Authorization header required; optional query: path, sort)
Response Schema: ApiResponse<FolderContentsVM>
Response DTO:
FolderContentsVM { Files: List<FileDetailsVM>, Folders: List<FolderDetailsVM> }
FileDetailsVM: { FileName, RelativePath, Extension, SizeInBytes, SizeInMB, CreationDate, LastModified }
FolderDetailsVM: { FolderName, RelativePath, CreationDate, SizeInBytes, SizeInMB }
POST /api/v1/files/upload uploads a file to the company file library using multipart/form-data. Use this endpoint to upload PDF, image, or font files into a target folder under Home.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
name
Folder name to create. Must be a single segment (no / or \\), cannot be “.” or “..”, cannot contain “..”, cannot be rooted, and cannot contain invalid file-name characters.
parentPath
Relative parent folder path. If omitted or blank, default is Home. Allowed format: relative path only; “.” and “..” segments are not allowed. If the value does not start with Home, the API prefixes Home/ automatically.
Folder created successfully.
Invalid input (for example: missing/invalid folder name, invalid parent path, parent path does not exist, folder already exists, or create operation failed).
Missing or invalid authentication token.
Authenticated token is valid, but access is denied by policy or path guard.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/files/folders” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d “{\”name\”:\”Invoices\”,\”parentPath\”:\”Home/2026\”}”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/files/folders” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“name”:”Invoices”,”parentPath”:”Home/2026″}’
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/files/folders” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“name”:”Invoices”,”parentPath”:”Home/2026″}’
JSON Request Body
{
"name": "Invoices",
"parentPath": "Home/2026"
}
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Folder created",
"data": {
"Path": "/Home/2026/Invoices",
"Name": "Invoices"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Failed to create folder",
"data": null,
"errors": ["Invalid folder input or parent path"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Unauthorized access.",
"data": null,
"errors": ["Forbidden"]
}
Request Schema: CreateFolderRequest { name: string, parentPath?: string }
Response Schema: ApiResponse<object>
Response DTO: object { Path, Name }
DELETE /api/v1/files deletes a file or folder from the company file library. Use this endpoint to remove unwanted files or folders (folder deletion is recursive).
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
path
Relative path of the target file or folder to delete. Must remain under Home. Deleting Home itself is not allowed.
File or folder deleted successfully.
Invalid request (for example: missing path, deleting Home, invalid target path, or delete operation failed).
Missing or invalid authentication token.
Authenticated token is valid, but access is denied by policy or path guard.
Request
cURL Request Example:
Windows cmd:
curl -X DELETE “{{baseUrl}}/api/v1/files?path=Home/2026/Invoices” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X DELETE “{{baseUrl}}/api/v1/files?path=Home/2026/Invoices” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X DELETE “{{baseUrl}}/api/v1/files?path=Home/2026/Invoices” -H “Authorization: Bearer <access-token>”
Request Example:
DELETE /api/v1/files?path=Home/2026/Invoices
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Deleted",
"data": {
"Path": "/Home/2026/Invoices"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Delete failed",
"data": null,
"errors": ["Invalid path or target not deletable"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Unauthorized access.",
"data": null,
"errors": ["Forbidden"]
}
Request Schema: None (Authorization header required; required query: path)
Response Schema: ApiResponse<object>
Response DTO: object { Path }
POST /api/v1/files/upload uploads a file to the company file library using multipart/form-data. Use this endpoint to upload PDF, image, or font files into a target folder under Home.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
File
File to upload. Allowed extensions: .pdf, .jpg, .jpeg, .png, .gif, .ttf, .otf, .woff, .woff2.
FolderPath
Target folder path under Home. If omitted/blank, default is Home. Must start with Home when provided (for example: Home or Home/SubFolder). “.” and “..” segments are not allowed.
File uploaded successfully.
Invalid upload request (for example: missing file, unsupported type, invalid folder path, folder does not exist, duplicate file name, or upload failed).
Missing or invalid authentication token.
Authenticated token is valid, but access is denied by policy or path guard.
Uploaded payload exceeds the configured request size limit.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/files/upload” -H “Authorization: Bearer <access-token>” -F “File=@C:/Temp/brochure.pdf” -F “FolderPath=Home/2026”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/files/upload” -H “Authorization: Bearer <access-token>” -F “File=@C:/Temp/brochure.pdf” -F “FolderPath=Home/2026”
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/files/upload” -H “Authorization: Bearer <access-token>” -F “File=@/tmp/brochure.pdf” -F “FolderPath=Home/2026”
Request Example:
POST /api/v1/files/upload (multipart/form-data)
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Uploaded",
"data": {
"FileName": "brochure.pdf",
"FolderPath": "/Home/2026"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Upload failed",
"data": null,
"errors": ["Invalid file, path, or duplicate upload"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Unauthorized access.",
"data": null,
"errors": ["Forbidden"]
}
HTTP/1.1 413 Payload Too Large
{
"success": false,
"message": "Uploaded payload exceeds allowed limit",
"data": null,
"errors": ["Payload too large"]
}
Request Schema: UploadRequest { File: IFormFile, FolderPath?: string }
Response Schema: ApiResponse<object>
Response DTO: object { FileName, FolderPath }
GET /api/v1/files/content downloads a file from the company file library by path. Use this endpoint to retrieve file content for local download or client-side rendering.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
path
Relative file path under Home (for example: Home/2026/brochure.pdf). Must resolve inside the allowed company Home root.
File stream returned successfully.
Partial stream returned when a valid Range header is used.
Invalid request (for example: missing path or invalid path format).
Missing or invalid authentication token.
Authenticated token is valid, but access is denied by policy or path guard.
File not found at the specified path.
Request
cURL Request Example:
Windows cmd:
curl -X GET “{{baseUrl}}/api/v1/files/content?path=Home/2026/brochure.pdf” -H “Authorization: Bearer <access-token>” -o “brochure.pdf”
PowerShell:
curl -X GET “{{baseUrl}}/api/v1/files/content?path=Home/2026/brochure.pdf” -H “Authorization: Bearer <access-token>” -o “brochure.pdf”
Linux/macOS:
curl -X GET “{{baseUrl}}/api/v1/files/content?path=Home/2026/brochure.pdf” -H “Authorization: Bearer <access-token>” -o “brochure.pdf”
Request Example:
GET /api/v1/files/content?path=Home/2026/brochure.pdf
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename="brochure.pdf"
[binary file stream]
HTTP/1.1 206 Partial Content
Content-Type: application/pdf
Content-Range: bytes 0-1023/245760
[partial binary file stream]
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Path is required.",
"data": null,
"errors": ["Invalid path"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Unauthorized access.",
"data": null,
"errors": ["Forbidden"]
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "File not found.",
"data": null,
"errors": ["Not found"]
}
JSON Response Body:
Success responses are binary streams. Error responses use ApiResponse<object>.
Request Schema: None (Authorization header required; required query: path)
Success Response Schema (200/206): Binary file stream
Error Response Schema (4xx): ApiResponse<object>
Success Response Shape: Streamed file bytes with response headers (Content-Type, Content-Disposition; Content-Range for partial content)
Error Response DTO: object { success, message, data, errors }
GET /api/v1/files/search performs a name-based search across the company file library. Use this endpoint to find files by keyword and retrieve basic file metadata.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
q
Search keyword used to match file names/paths.
Search completed successfully (may return an empty list).
Query parameter is missing or invalid.
Missing or invalid authentication token.
Authenticated token is valid, but access is denied by policy.
Request
cURL Request Example:
Windows cmd:
curl -X GET “{{baseUrl}}/api/v1/files/search?q=brochure” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X GET “{{baseUrl}}/api/v1/files/search?q=brochure” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X GET “{{baseUrl}}/api/v1/files/search?q=brochure” -H “Authorization: Bearer <access-token>”
Request Example:
GET /api/v1/files/search?q=brochure
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Search results",
"data": [
{
"FileName": "brochure.pdf",
"FullPath": "Home/2026",
"CreationTime": "2/27/2026 10:12:00 AM",
"LastWriteTime": "2/27/2026 10:15:00 AM"
}
],
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Query required.",
"data": null,
"errors": ["Missing query parameter q"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
Request Schema: None (Authorization header required; required query: q)
Response Schema: ApiResponse<List<SearchedFilesInAssetViewModel>>
Response DTO: SearchedFilesInAssetViewModel { FileName, FullPath, CreationTime, LastWriteTime }
POST /api/v1/files/rename renames an existing file or folder inside the company file library. Use this endpoint when you need to change a file name or folder name under a target relative path (default location resolves to Home when relativePath is omitted).
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
relativePath
Relative directory path containing the item to rename. If omitted/blank, it resolves to Home.
oldFileName
Current file or folder name to rename.
newFileName
New file or folder name. If renaming a file, extension/type must remain allowed by platform rules.
Item renamed successfully.
Invalid request (for example: missing names, invalid path guard failure, unsupported file type on file rename, rename exception, or rename log failure).
Missing or invalid authentication token.
Authenticated token is valid, but access is denied by policy or path guard.
Source file/folder to rename does not exist.
Target name already exists in the same directory.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/files/rename” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d “{\”relativePath\”:\”Home/2026\”,\”oldFileName\”:\”brochure.pdf\”,\”newFileName\”:\”brochure-final.pdf\”}”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/files/rename” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“relativePath”:”Home/2026″,”oldFileName”:”brochure.pdf”,”newFileName”:”brochure-final.pdf”}’
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/files/rename” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“relativePath”:”Home/2026″,”oldFileName”:”brochure.pdf”,”newFileName”:”brochure-final.pdf”}’
JSON Request Body
{
"relativePath": "Home/2026",
"oldFileName": "brochure.pdf",
"newFileName": "brochure-final.pdf"
}
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Renamed",
"data": {
"RelativePath": "/Home/2026",
"OldName": "brochure.pdf",
"NewName": "brochure-final.pdf"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Old and new names are required.",
"data": null,
"errors": ["Invalid rename request"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Unauthorized access.",
"data": null,
"errors": ["Forbidden"]
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Item not found.",
"data": null,
"errors": ["Not found"]
}
HTTP/1.1 409 Conflict
{
"success": false,
"message": "A file with this name already exists.",
"data": null,
"errors": ["Conflict"]
}
Request Schema: RenameRequest { relativePath?: string, oldFileName: string, newFileName: string }
Response Schema: ApiResponse<object>
Response DTO: object { RelativePath, OldName, NewName }
GET /api/v1/recipients returns recipients for the authenticated company using offset/limit pagination. It can optionally filter by recipient group. Use this endpoint to build recipient tables, paging UI, and group-specific recipient views.
Authorization
Bearer access token in the format: Authorization: Bearer .
groupId
Recipient group ID filter. If omitted or set to 0, all groups are returned.
offset
Number of recipient records to skip before returning results (pagination cursor). Use with `limit`; if omitted, starts from the first record (0).
limit
Maximum number of recipients to return. Default is 100.
Recipient list returned successfully.
Invalid input (for example: groupId is not a valid GUID).
Missing or invalid authentication token, or CompanyId claim is missing/invalid.
Authenticated token is valid, but does not have Recipient.Read permission.
Request
cURL Request Example:
Windows cmd:
curl -X GET “{{baseUrl}}/api/v1/recipients?groupId=0&offset=0&limit=100” -H “Authorization: Bearer ”
PowerShell:
curl -X GET “{{baseUrl}}/api/v1/recipients?groupId=0&offset=0&limit=100” -H “Authorization: Bearer ”
Linux/macOS:
curl -X GET “{{baseUrl}}/api/v1/recipients?groupId=0&offset=0&limit=100” -H “Authorization: Bearer ”
Request Example:
GET /api/v1/recipients?groupId=0&offset=0&limit=100
JSON Request Body:
No request body is required.
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Recipients list",
"data": {
"total": 1,
"offset": 0,
"limit": 100,
"hasMore": false,
"nextOffset": null,
"data": [
{
"recipientId": "6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5",
"title": "Mr",
"firstName": "John",
"lastName": "Doe",
"companyName": "Example Ltd",
"address1": "1 Main Street",
"address2": null,
"address3": null,
"address4": null,
"postCode": "SW1A 1AA",
"city": "London",
"countyName": "Greater London",
"countryName": "United Kingdom",
"customFields": {
"MemberId": "A1029"
}
}
]
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "recipientGroupId is not a valid GUID.",
"data": null,
"errors": ["Validation failed"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
Request Schema: None (Authorization header required; optional query: groupId, offset, limit)
Response Schema: ApiResponse
Response DTO: RecipientListDataDto { Total, Offset, Limit, HasMore, NextOffset, Data:
List }
RecipientListItemOutDto: { RecipientId, Title, FirstName, LastName, CompanyName, Address1, Address2, Address3, Address4, PostCode, City, CountyName, CountryName, CustomFields }
POST /api/v1/recipients creates a new recipient record in your account. Use this endpoint when adding a recipient to a specific recipient group or to the default recipient group when no group is provided.
Authorization
Bearer access token in the format: Authorization: Bearer .
Title
Recipient title (for example: Mr, Ms).
FirstName
Recipient first name.
LastName
Recipient last name.
Address1
Primary address line (max 255).
Address2
Secondary address line (max 255).
Postcode
Post code (max 255).
City
City/town name (max 255).
Address3
Additional address line (max 150).
Address4
Additional address line (max 150).
CompanyName
Company name (max 100).
CountryName
Country name as free text (max 100).
CountyName
County name as free text (max 100).
GroupId
Target recipient group ID for the new recipient. Must be a valid GUID and belong to the authenticated company. If omitted, API resolves and uses the company default recipient group.
CustomFields
Optional key/value custom fields supplied by client integrations. Include this when your workflow captures extra recipient metadata.
Recipient created successfully.
Validation or business rule failure (for example: missing required `Address1`/`Postcode`, invalid `GroupId` format, group not in company scope, or no default group configured).
Missing or invalid authentication token, or CompanyId claim is missing/invalid.
Forbidden. You don’t have permission to access this resource.
Request
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/recipients” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d “{\”title\”:\”Mr\”,\”firstName\”:\”John\”,\”lastName\”:\”Doe\”,\”address1\”:\”1 Main Street\”,\”address2\”:\”Flat 2\”,\”postcode\”:\”SW1A 1AA\”,\”city\”:\”London\”,\”companyName\”:\”Example Ltd\”,\”countryName\”:\”United Kingdom\”,\”countyName\”:\”Greater London\”,\”groupId\”:\”a4f1f7f6-74f4-45fa-a211-7ad10d15858d\”,\”customFields\”:{\”MemberId\”:\”A1029\”}}”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/recipients” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“title”:”Mr”,”firstName”:”John”,”lastName”:”Doe”,”address1″:”1 Main Street”,”address2″:”Flat 2″,”postcode”:”SW1A 1AA”,”city”:”London”,”companyName”:”Example Ltd”,”countryName”:”United Kingdom”,”countyName”:”Greater London”,”groupId”:”a4f1f7f6-74f4-45fa-a211-7ad10d15858d”,”customFields”:{“MemberId”:”A1029″}}’
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/recipients” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“title”:”Mr”,”firstName”:”John”,”lastName”:”Doe”,”address1″:”1 Main Street”,”address2″:”Flat 2″,”postcode”:”SW1A 1AA”,”city”:”London”,”companyName”:”Example Ltd”,”countryName”:”United Kingdom”,”countyName”:”Greater London”,”groupId”:”a4f1f7f6-74f4-45fa-a211-7ad10d15858d”,”customFields”:{“MemberId”:”A1029″}}’
JSON Request Body:
{
"title": "Mr",
"firstName": "John",
"lastName": "Doe",
"address1": "1 Main Street",
"address2": "Flat 2",
"postcode": "SW1A 1AA",
"city": "London",
"address3": null,
"address4": null,
"companyName": "Example Ltd",
"countryName": "United Kingdom",
"countyName": "Greater London",
"groupId": "a4f1f7f6-74f4-45fa-a211-7ad10d15858d",
"customFields": {
"MemberId": "A1029"
}
}
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Recipient created",
"data": {
"recipientId": "6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Validation failed",
"data": null,
"errors": [
"The Address1 field is required.",
"The Postcode field is required."
]
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "GroupId is not a valid GUID.",
"data": null,
"errors": [
"Validation failed"
]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": [
"Unauthorized"
]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": [
"Forbidden"
]
}
Request Schema: CreateRecipientRequest { Title?: string, FirstName?: string, LastName?: string, Address1: string, Address2?: string, Postcode: string, City?: string, Address3?: string, Address4?: string, CompanyName?: string, CountryName?: string, CountyName?: string, GroupId?: string, CustomFields?: Dictionary<string,string> }
Response Schema: ApiResponse<object>
Response DTO: object { recipientId }
Return Value Details:
– success (boolean): `true` when recipient creation succeeds; `false` when validation/business checks fail.
– message (string): Outcome summary such as `Recipient created`, `Validation failed`, or claim/group validation errors.
– data (object | null): On success, returns `{ recipientId }`; on failure, `null`.
– errors (array<string> | null): Validation details when model validation fails; otherwise may be `null` depending on failure path.
GET /api/v1/recipients/{id} returns full details for a single recipient record. Use this endpoint to view recipient details, prefill update flows, and supply recipient data to campaign workflows.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
id
Recipient ID to fetch. Must be a valid GUID in the route.
Recipient details returned successfully.
Missing or invalid authentication token.
Authenticated token is valid, but does not have permission to read recipient details.
Recipient does not exist or is not accessible.
Request
cURL Request Example:
Windows cmd:
curl -X GET “{{baseUrl}}/api/v1/recipients/6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X GET “{{baseUrl}}/api/v1/recipients/6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X GET “{{baseUrl}}/api/v1/recipients/6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5” -H “Authorization: Bearer <access-token>”
Request Example:
GET /api/v1/recipients/6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Recipient details",
"data": {
"id": "6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5",
"title": "Mr",
"firstName": "John",
"lastName": "Doe",
"address1": "1 Main Street",
"address2": "Flat 2",
"address3": null,
"address4": null,
"address5": null,
"city": "London",
"companyName": "Example Ltd",
"countryName": "United Kingdom",
"countyName": "Greater London",
"postcode": "SW1A 1AA",
"customFields": {
"MemberId": "A1029"
}
},
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid credentials",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Recipient not found.",
"data": null,
"errors": ["Not found"]
}
Request Schema: None (Authorization header required; path parameter: id)
Response Schema: ApiResponse<RecipientDetailsResponse>
Response DTO: RecipientDetailsResponse { Id, Title, FirstName, LastName, Address1, Address2, Address3, Address4, Address5, City, CompanyName, CountryName, CountyName, Postcode, CustomFields }
Return Value Details:
– success (boolean): `true` when recipient lookup succeeds; `false` on auth/permission/not-found outcomes.
– message (string): Outcome summary such as `Recipient details` or `Recipient not found.`
– data (RecipientDetailsResponse | null): Recipient payload on success; `null` when request fails.
– errors (array<string> | null): Optional failure details depending on middleware/controller failure path.
– customFields (object<string,string> | null): Dynamic key/value metadata associated with the recipient record.
PUT /api/v1/recipients/{id} updates an existing recipient record. This endpoint supports partial updates, so only fields provided in the request body are changed. Use this endpoint when a client needs to correct or enrich recipient profile data.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
id
Unique recipient identifier to update.
Id
Optional recipient identifier in the request body. If provided, it must match the route `id`.
Title
Recipient title (for example: Mr, Ms, Dr).
FirstName
Recipient first name.
LastName
Recipient last name.
Address1
Primary street address line.
Address2
Secondary address line (for example: apartment, suite, unit).
Address3
Additional address line.
Address4
Additional address line.
Address5
Additional address line.
City
City or town name.
CompanyName
Recipient company or organization name (for business addresses).
Postcode
Postal code for the recipient address. Response values may be returned in uppercase.
CountryName
Country name for the recipient address (example: United Kingdom).
CountyName
County/region name for the recipient address (example: Cambridgeshire).
Recipient updated successfully.
Validation or business rule failure (for example: body `Id` does not match route `id`, or recipient cannot be updated).
Missing or invalid authentication token.
Authenticated token is valid, but does not have permission to update recipients.
Recipient does not exist.
Request
cURL Request Example:
Windows cmd:
curl -X PUT “{{baseUrl}}/api/v1/recipients/6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d “{\”firstName\”:\”Jane\”,\”lastName\”:\”Doe\”,\”postcode\”:\”sw1a 1aa\”,\”city\”:\”London\”}”
PowerShell:
curl -X PUT “{{baseUrl}}/api/v1/recipients/6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“firstName”:”Jane”,”lastName”:”Doe”,”postcode”:”sw1a 1aa”,”city”:”London”}’
Linux/macOS:
curl -X PUT “{{baseUrl}}/api/v1/recipients/6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“firstName”:”Jane”,”lastName”:”Doe”,”postcode”:”sw1a 1aa”,”city”:”London”}’
JSON Request Body:
{
"id": "6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5",
"title": "Ms",
"firstName": "Jane",
"lastName": "Doe",
"address1": "1 Main Street",
"address2": "Flat 2",
"address3": null,
"address4": null,
"address5": null,
"city": "London",
"companyName": "Example Ltd",
"postcode": "sw1a 1aa",
"countryName": "United Kingdom",
"countyName": "Cambridgeshire"
}
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Recipient updated",
"data": {
"recipientId": "6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Body Id does not match route Id.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Recipient cannot be updated.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Validation failed",
"data": null,
"errors": ["One or more request fields are invalid."]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid credentials",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Recipient not found.",
"data": null,
"errors": ["Not found"]
}
Request Schema:
UpdateRecipientRequest {
Id?: Guid,
Title?: string,
FirstName?: string,
LastName?: string,
Address1?: string,
Address2?: string,
Address3?: string,
Address4?: string,
Address5?: string,
City?: string,
CompanyName?: string,
Postcode?: string,
CountryName?: string,
CountyName?: string
}
Response Schema: ApiResponse<object>
Response DTO:
object {
recipientId
}
Return Value Details:
– success (boolean): `true` when update succeeds; `false` on validation/auth/permission/not-found failures.
– message (string): Outcome summary such as `Recipient updated`, `Body Id does not match route Id.`, or `Recipient not found.`
– data (object | null): On success returns `{ recipientId }`; otherwise `null`.
– errors (array<string> | null): Optional list of failure details.
DELETE /api/v1/recipients/{id} deletes a recipient record by ID. Use this endpoint to remove a recipient when it is no longer needed.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
id
Recipient ID to delete.
Recipient deleted successfully.
Recipient cannot be deleted due to business rules (for example: linked to an active campaign or restricted recipient type).
Missing or invalid authentication token.
Authenticated token is valid, but does not have permission to delete recipients.
Recipient does not exist.
Request
cURL Request Example:
Windows cmd:
curl -X DELETE “{{baseUrl}}/api/v1/recipients/6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X DELETE “{{baseUrl}}/api/v1/recipients/6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X DELETE “{{baseUrl}}/api/v1/recipients/6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5” -H “Authorization: Bearer <access-token>”
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Recipient deleted",
"data": {
"recipientId": "6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "This recipient is associated with an active campaign and cannot be deleted right now.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Recipient cannot be deleted due to current recipient type restrictions.",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid credentials",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Recipient not found.",
"data": null,
"errors": ["Not found"]
}
Request Schema: None (Authorization header required; path parameter: id)
Response Schema: ApiResponse<object>
Response DTO:
object {
recipientId
}
Return Value Details:
– success (boolean): `true` when deletion succeeds; `false` when authorization, not-found, or business checks fail.
– message (string): Outcome summary such as `Recipient deleted` or a business-rule failure message.
– data (object | null): On success returns `{ recipientId }`; otherwise `null`.
– errors (array<string> | null): Optional list of failure details.
POST /api/v1/recipients/import starts an asynchronous recipient import job and creates a new recipient group from the provided groupName. The file source can be supplied as Base64 content (fileData) or as a downloadable URL (fileUrl). Use this endpoint to bulk import recipient records from CSV/XLSX files.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
groupName
Name of the new recipient group to create for this import. Must be unique within your account.
fileName
Original file name including extension (for example: `recipients.csv`, `recipients.xlsx`).
fileData
Conditionally required – Base64-encoded file content. Required when `fileUrl` is not provided.
fileUrl
Conditionally required – Direct URL to a raw downloadable CSV/XLSX file. Required when `fileData` is not provided.
mappings
Column mapping definitions.
mappings[].sourceHeader
Source column header name from the input file.
mappings[].destinationField
Target system field name when mapping to a standard field.
mappings[].mappingType
Mapping behavior. Allowed values: `standard`, `custom`, `skip`. Default: none (must be provided). Fallback behavior: values other than `skip` are processed; `skip` columns are ignored.
Import request accepted and queued for background processing.
Invalid request payload or business validation failure (for example: missing group name, duplicate group, invalid URL, invalid file source combination, missing mappings).
Missing or invalid authentication token.
Authenticated token is valid, but does not have permission to import recipients.
Server failed while saving/pre-processing the uploaded file.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/recipients/import” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d “{\”groupName\”:\”March Import\”,\”fileName\”:\”recipients.csv\”,\”fileData\”:\”<base64-encoded-file-content>\”,\”mappings\”:[{\”sourceHeader\”:\”First Name\”,\”destinationField\”:\”FirstName\”,\”mappingType\”:\”standard\”},{\”sourceHeader\”:\”Last Name\”,\”destinationField\”:\”LastName\”,\”mappingType\”:\”standard\”},{\”sourceHeader\”:\”MemberId\”,\”destinationField\”:\”MemberId\”,\”mappingType\”:\”custom\”}]}”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/recipients/import” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“groupName”:”March Import”,”fileName”:”recipients.csv”,”fileData”:”<base64-encoded-file-content>”,”mappings”:[{“sourceHeader”:”First Name”,”destinationField”:”FirstName”,”mappingType”:”standard”},{“sourceHeader”:”Last Name”,”destinationField”:”LastName”,”mappingType”:”standard”},{“sourceHeader”:”MemberId”,”destinationField”:”MemberId”,”mappingType”:”custom”}]}’
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/recipients/import” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“groupName”:”March Import”,”fileName”:”recipients.csv”,”fileData”:”<base64-encoded-file-content>”,”mappings”:[{“sourceHeader”:”First Name”,”destinationField”:”FirstName”,”mappingType”:”standard”},{“sourceHeader”:”Last Name”,”destinationField”:”LastName”,”mappingType”:”standard”},{“sourceHeader”:”MemberId”,”destinationField”:”MemberId”,”mappingType”:”custom”}]}’
JSON Request Body Example 1 (Base64 source)
{
"groupName": "March Import",
"fileName": "recipients.csv",
"fileData": "",
"mappings": [
{
"sourceHeader": "First Name",
"destinationField": "FirstName",
"mappingType": "standard"
},
{
"sourceHeader": "Last Name",
"destinationField": "LastName",
"mappingType": "standard"
},
{
"sourceHeader": "MemberId",
"destinationField": "MemberId",
"mappingType": "custom"
}
]
}
JSON Request Body Example 2 (URL link source)
{
"groupName": "March Import",
"fileName": "recipients.xlsx",
"fileUrl": "https://example.com/exports/recipients.xlsx",
"mappings": [
{
"sourceHeader": "First Name",
"destinationField": "FirstName",
"mappingType": "standard"
},
{
"sourceHeader": "Last Name",
"destinationField": "LastName",
"mappingType": "standard"
},
{
"sourceHeader": "Notes",
"destinationField": "Notes",
"mappingType": "skip"
}
]
}
Copied!
Response
cURL Response Example:
HTTP/1.1 202 Accepted
{
"success": true,
"message": null,
"data": {
"message": "Your file has been accepted and is being processed.",
"jobId": "d5fa2f56-7d11-4f87-8f95-d0a3b6a1f17f"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "You must provide either 'fileData' (Base64) or a 'fileUrl'.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "A group with this name already exists. Please choose a different name.",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid credentials",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An internal error occurred while processing the file.",
"data": null,
"errors": null
}
JSON Response Body:
The API returns immediately with `202 Accepted`. Import execution continues in the background. To check import status, call `/api/v1/groups/by-name` using the imported `groupName`.
Request Schema:
RecipientImportRequest {
fileData?: string,
fileUrl?: string,
fileName: string,
groupName: string,
mappings: List
}
ColumnMapping:
{
sourceHeader: string,
destinationField: string,
mappingType: string (`standard` | `custom` | `skip`)
}
Response Schema (202): ApiResponse<object>
Response DTO (202):
object {
message,
jobId
}
Return Value Details:
– success (boolean): `true` when the import job is accepted; `false` when request validation or pre-processing fails.
– message (string | null): For accepted responses, message may be in `data.message`; for failures, top-level `message` describes the issue.
– data (object | null): On `202`, returns `{ message, jobId }`; on error, returns `null`.
– errors (array<string> | null): Optional list of failure details.
GET /api/v1/groups returns a paginated list of recipient groups in your account. Use this endpoint to load group lists in your UI, including each group’s name, recipient count, default-group flag, and timestamps.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
offset
Number of records to skip before returning results. Default is 0.
limit
Maximum number of groups to return. Default is 100.
Group list returned successfully.
Missing or invalid authentication token.
Authenticated token is valid, but permission is denied.
Unexpected error while retrieving groups.
Request
cURL Request Example:
Windows cmd:
curl -X GET “{{baseUrl}}/api/v1/groups?offset=0&limit=100” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X GET “{{baseUrl}}/api/v1/groups?offset=0&limit=100” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X GET “{{baseUrl}}/api/v1/groups?offset=0&limit=100” -H “Authorization: Bearer <access-token>”
Request Example:
GET /api/v1/groups?offset=0&limit=100
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Groups list retrieved successfully.",
"data": {
"total": 2,
"offset": 0,
"limit": 100,
"hasMore": false,
"nextOffset": null,
"data": [
{
"id": "0f710b4e-99d8-4b59-b793-a5db290df77f",
"groupName": "March Import",
"recipientCount": 1200,
"isDefaultGroup": false,
"createdDate": "2026-03-08T10:35:12Z",
"updatedDate": "2026-03-08T11:10:04Z"
}
]
},
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": ["Internal server error"]
}
Request Schema: None (Authorization header required; optional query: offset, limit)
Response Schema: ApiResponse<GroupListDataDto>
Response DTO:
GroupListDataDto {
Total,
Offset,
Limit,
HasMore,
NextOffset,
Data: List
}
GroupListItemDto:
{
Id,
GroupName,
RecipientCount,
IsDefaultGroup,
CreatedDate,
UpdatedDate
}
POST /api/v1/groups creates a new recipient group in your account. Use this endpoint when you need a new destination group before adding recipients manually or via import.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
groupName
Display name for the new recipient group. The name must be unique within your account.
Group created successfully.
Invalid request payload (for example: missing or empty group name).
Missing or invalid authentication token.
Authenticated token is valid, but permission is denied.
A group with the same name already exists.
Unexpected error while creating the group.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/groups” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d “{\”groupName\”:\”Spring Campaign Audience\”}”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/groups” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“groupName”:”Spring Campaign Audience”}’
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/groups” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“groupName”:”Spring Campaign Audience”}’
JSON Request Body:
{
"groupName": "Spring Campaign Audience"
}
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Group created",
"data": {
"id": "0f710b4e-99d8-4b59-b793-a5db290df77f",
"groupName": "Spring Campaign Audience",
"fileName": null,
"isDefaultGroup": false,
"recipientCount": 0,
"createdDate": "2026-03-09T09:00:00Z",
"updatedDate": null,
"failedRecords": 0,
"totalRecords": null,
"status": "ready"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Group name is required.",
"data": null,
"errors": ["Validation failed"]
}
HTTP/1.1 409 Conflict
{
"success": false,
"message": "A group with the same name already exists in this company.",
"data": null,
"errors": ["Conflict"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
Request Schema:
CreateGroupRequest {
GroupName: string
}
Response Schema: ApiResponse<GroupDetailDto>
Response DTO:
GroupDetailDto {
Id,
GroupName,
FileName,
IsDefaultGroup,
RecipientCount,
CreatedDate,
UpdatedDate,
FailedRecords,
TotalRecords,
Status
}
POST /api/v1/groups/{groupId}/recipients-remove removes selected recipients from a specific group. Use this endpoint to update group membership while keeping recipient records available in your account.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
groupId
Recipient group identifier.
recipientIds
List of recipient IDs to remove from the group.
Recipients removed from the group successfully.
Invalid request or business-rule validation failed (for example: empty recipient list).
Missing or invalid authentication token.
Authenticated token is valid, but permission is denied.
Unexpected error while removing recipients.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/groups/0f710b4e-99d8-4b59-b793-a5db290df77f/recipients-remove” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d “{\”recipientIds\”:[\”6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5\”,\”bf2c1f5e-2fc4-4ec5-9987-bf7a6b2be2f1\”]}”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/groups/0f710b4e-99d8-4b59-b793-a5db290df77f/recipients-remove” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“recipientIds”:[“6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5″,”bf2c1f5e-2fc4-4ec5-9987-bf7a6b2be2f1”]}’
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/groups/0f710b4e-99d8-4b59-b793-a5db290df77f/recipients-remove” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“recipientIds”:[“6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5″,”bf2c1f5e-2fc4-4ec5-9987-bf7a6b2be2f1”]}’
JSON Request Body:
{
"recipientIds": [
"6e4d31d5-7dd2-48f8-b8a6-4521b8a447d5",
"bf2c1f5e-2fc4-4ec5-9987-bf7a6b2be2f1"
]
}
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Recipients removed from group",
"data": {
"groupId": "0f710b4e-99d8-4b59-b793-a5db290df77f",
"removed": 2
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "RecipientIds is required.",
"data": null,
"errors": ["Validation failed"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
Request Schema:
RemoveRecipientsRequest {
RecipientIds: List
}
Response Schema: ApiResponse<object>
Response DTO:
object {
GroupId,
Removed
}
DELETE /api/v1/groups/{groupId} deletes a recipient group by ID. Use this endpoint when a group is no longer needed and should no longer appear in group listings.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
groupId
Recipient group identifier to delete.
Group deleted successfully.
Group cannot be deleted due to current validation or business rules.
Missing or invalid authentication token.
Authenticated token is valid, but permission is denied.
Unexpected error while deleting the group.
Request
cURL Request Example:
Windows cmd:
curl -X DELETE “{{baseUrl}}/api/v1/groups/0f710b4e-99d8-4b59-b793-a5db290df77f” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X DELETE “{{baseUrl}}/api/v1/groups/0f710b4e-99d8-4b59-b793-a5db290df77f” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X DELETE “{{baseUrl}}/api/v1/groups/0f710b4e-99d8-4b59-b793-a5db290df77f” -H “Authorization: Bearer <access-token>”
Request Example:
DELETE /api/v1/groups/0f710b4e-99d8-4b59-b793-a5db290df77f
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Group deleted",
"data": {
"groupId": "0f710b4e-99d8-4b59-b793-a5db290df77f"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Group cannot be deleted in its current state.",
"data": null,
"errors": ["Validation failed"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
Request Schema: None (Authorization header required; path parameter: groupId)
Response Schema: ApiResponse<object>
Response DTO:
object {
GroupId
}
GET /api/v1/groups/by-name returns full details for a recipient group that matches the provided name. Use this endpoint after import submission to check whether the group is available, monitor progress (status), and review result counts (recipientCount, failedRecords, and totalRecords).
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
name
Exact group name to look up.
Group details returned successfully.
Required query parameter is missing or invalid.
Missing or invalid authentication token.
Authenticated token is valid, but permission is denied.
No group found with the provided name.
Unexpected error while retrieving group details.
Request
cURL Request Example:
Windows cmd:
curl -X GET “{{baseUrl}}/api/v1/groups/by-name?name=March%20Import” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X GET “{{baseUrl}}/api/v1/groups/by-name?name=March%20Import” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X GET “{{baseUrl}}/api/v1/groups/by-name?name=March%20Import” -H “Authorization: Bearer <access-token>”
Request Example:
GET /api/v1/groups/by-name?name=March%20Import
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Group details",
"data": {
"id": "0f710b4e-99d8-4b59-b793-a5db290df77f",
"groupName": "March Import",
"fileName": "recipients.csv",
"isDefaultGroup": false,
"recipientCount": 1200,
"createdDate": "2026-03-08T10:35:12Z",
"updatedDate": "2026-03-08T11:10:04Z",
"failedRecords": 12,
"totalRecords": 1212,
"status": "ready"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "name is required",
"data": null,
"errors": ["Validation failed"]
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Group not found",
"data": null,
"errors": ["Not found"]
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
Request Schema: None (Authorization header required; required query: name)
Response Schema: ApiResponse<GroupDetailDto>
Response DTO:
GroupDetailDto {
Id,
GroupName,
FileName,
IsDefaultGroup,
RecipientCount,
CreatedDate,
UpdatedDate,
FailedRecords,
TotalRecords,
Status
}
Return Value Details:
– success (boolean): `true` when a matching group is found; `false` for validation, authorization, or not-found outcomes.
– message (string): Human-readable result summary, such as `Group details` or `Group not found`.
– data (GroupDetailDto | null): Group payload when available; `null` on failures.
– errors (array<string> | null): Optional list of error details.
GET /api/v1/template returns a paginated list of templates available to the authenticated account. Use this endpoint when building template pickers, filtering template options by format, or loading template lists page by page. This endpoint is useful for external API consumers and integration developers who need to display or filter templates before campaign creation, and to retrieve a valid templateId when using an existing template in campaign creation.
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
offset
Number of records to skip before returning results. Default is 0.
limit
Maximum records to return. Default is 50 when omitted. If set to 0, a negative number, or a value greater than 200, the API uses 100.
pageOrientation
Filter by page orientation. Use a supported orientation value. For filter fields (`pageOrientation`, `pageSize`, `windowGummedCode`), invalid values return HTTP 400 and include allowed values in the response.
pageSize
Filter by page size. Use a supported page size value. For filter fields (`pageOrientation`, `pageSize`, `windowGummedCode`), invalid values return HTTP 400 and include allowed values in the response.
windowGummedCode
Filter by envelope/window code. Use a supported code value. For filter fields (`pageOrientation`, `pageSize`, `windowGummedCode`), invalid values return HTTP 400 and include allowed values in the response.
Template list returned successfully.
One or more filter values are invalid.
Missing or invalid authentication token.
Authenticated token is valid, but permission is denied.
Unexpected server error.
Request
cURL Request Example:
Windows cmd:
curl -X GET “{{baseUrl}}/api/v1/template?offset=0&limit=50&pageOrientation=Portrait&pageSize=A4%20Letter” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X GET “{{baseUrl}}/api/v1/template?offset=0&limit=50&pageOrientation=Portrait&pageSize=A4%20Letter” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X GET “{{baseUrl}}/api/v1/template?offset=0&limit=50&pageOrientation=Portrait&pageSize=A4%20Letter” -H “Authorization: Bearer <access-token>”
Request Example:
GET /api/v1/template?offset=0&limit=50&pageOrientation=Portrait&pageSize=A4%20Letter
Copied!
Response
cURL Response Example:
HTTP/1.1 200 OK
{
"success": true,
"message": "Templates fetched successfully.",
"data": {
"total": 2,
"offset": 0,
"limit": 50,
"hasMore": false,
"nextOffset": null,
"items": [
{
"id": 101,
"pageOrientation": "Portrait",
"pageSize": "A4 Letter",
"windowGummedCode": "C5",
"name": "Spring Offer Template",
"createdDate": "2026-01-15T09:30:00Z",
"updatedDate": "2026-02-01T11:45:00Z"
}
]
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "One or more filter values are invalid.",
"data": {
"error": "Invalid pageSize: 'A0'.",
"validPageSizes": ["A4 Letter", "A5"]
},
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Missing or invalid authentication token",
"data": null,
"errors": ["Unauthorized"]
}
HTTP/1.1 403 Forbidden
{
"success": false,
"message": "Authenticated token is valid, but permission is denied",
"data": null,
"errors": ["Forbidden"]
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "Unexpected server error",
"data": null,
"errors": ["Internal server error"]
}
Request Schema: None (Authorization header required; optional query: offset, limit, pageOrientation, pageSize, windowGummedCode)
Response Schema: ApiResponse<PagedResult<TemplateDto>>
Response DTO:
PagedResult {
Total,
Offset,
Limit,
HasMore,
NextOffset,
Items: List
}
TemplateDto:
{
Id,
PageOrientation,
PageSize,
WindowGummedCode,
Name,
CreatedDate,
UpdatedDate
}
Return Value Details:
– success (boolean): `true` when templates are returned; `false` when request validation or authorization fails.
– message (string): Human-readable result summary.
– data (PagedResult<TemplateDto> | object | null): On success, paginated template payload; on filter validation failure, error details with allowed values; otherwise `null`.
– errors (array<string> | null): Optional error list depending on failure type.
Campaign workflow
The steps below outline the typical end-to-end flow for creating, reviewing, and dispatching a campaign through the API. Follow them in order to ensure all required checks (preview, approval, cost, scheduling) are completed before dispatch.
- Get template options from
/api/v1/templateand choose atemplateId(or preparepdf). - Create the campaign using
/api/v1/campaignsand store returnedcampaignId. - Review campaign setup with
/api/v1/campaigns/{campaignId}and preview PDF via/api/v1/campaigns/{campaignId}/preview. - Approve campaign using
/api/v1/campaigns/approve. - Optionally apply/remove voucher with
/api/v1/campaigns/voucher. - Review pricing using
/api/v1/campaigns/cost. - Get dates from
/api/v1/campaigns/availableDates, then schedule via/api/v1/campaigns/schedule. - Track progress with
/api/v1/campaigns/statusDetails.
Supported Format Combinations
The campaign.pageOrientation, campaign.pageSize, and campaign.windowGummedCode fields must match one of the combinations listed below. Any other combination will result in an invalid format error.
| # | pageOrientation | pageSize | windowGummedCode |
|---|---|---|---|
| 1 | Portrait | A5 Tabbed Greeting Card | not required |
| 2 | Landscape | A5 Postcard | not required |
| 3 | Landscape | A5 Enveloped Postcard | C5NONWINDOW |
| 4 | Portrait | A4 Letter | C4WIN |
| 5 | Landscape | A5 Enveloped Greeting Card | C5NONWINDOW |
| 6 | Portrait | A4 Letter | C5NONWINDOW |
| 7 | Portrait | A5 Postcard | not required |
| 8 | Portrait | A4 Letter | C5WIN |
| 9 | Landscape | A6 Postcard | not required |
| 10 | Landscape | DL Postcard | not required |
When windowGummedCode is marked “not required”, omit the field or pass null.
POST /api/v1/campaigns creates a new campaign for the authenticated account. Use this endpoint after selecting a templateId from /api/v1/template, or by sending a PDF to create a campaign from uploaded content. The response returns campaignId, which is used by other campaign endpoints (details, preview, approve, voucher, cost, schedule, status, delete).
Authorization
Bearer access token in the format: Authorization: Bearer <token>.
campaign
Campaign settings container.
campaign.name
Campaign display name.
campaign.pageSize
Page size value. Must be a supported format.
campaign.pageOrientation
Page orientation value. Must be a supported format.
campaign.windowGummedCode
Envelope/window code for the selected format.
campaign.defaultRecipientName
Optional default recipient label.
campaign.recipients
Optional initial recipient selection.
campaign.recipients.type
Allowed values: group, single. If campaign.recipients.type is provided, campaign.recipients.id must be provided.
campaign.recipients.id
Required when campaign.recipients.type is provided.
campaign.stockWeightCode
campaign.stockWeightCode – string – Yes – Stock option code for the selected format. Allowed values: 100UNCOAT, 120UNCOAT, 250SILK, 300GLOSS, 350SILK, 350UNCOAT.
campaign.mailClassCode
Mail class code for the selected format.
campaign.isDuplex
Duplex printing flag.
campaign.isAdmail
Admail flag.
campaign.isConfidential
Confidential flag.
templateId
Conditionally required – Existing template ID from /api/v1/template. Provide this or pdf. Use this when creating a campaign from a previously saved design template.
PDF source object used to create a campaign without an existing template.
pdf.fileUrl
Conditionally required – Publicly reachable direct PDF URL. Use this when the document is hosted online.
pdf.fileBase64
Conditionally required – Base64-encoded PDF content. Use this when uploading inline file content from client applications.
pdf.originalName
Original source file name (for traceability/display).
pdf.fileName
Target file name used during processing/storage.
templateName
Optional name for the generated template when using pdf source.
Campaign created successfully.
Invalid payload or unsupported format/options.
Missing or invalid authentication token.
Template/group/recipient not found.
Uploaded PDF exceeds allowed size.
No page layout defined for the requested format combination, or campaign settings do not match the template’s settings.
Unexpected server error.
Request
Request examples below show all supported creation modes.
cURL Request Example: Mode A (Use Existing Template Design via `templateId`)
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/campaigns” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d “{\”campaign\”:{\”name\”:\”Spring Campaign (Template)\”,\”pageSize\”:\”A4 Letter\”,\”pageOrientation\”:\”Portrait\”,\”windowGummedCode\”:\”C5\”,\”defaultRecipientName\”:\”Customer\”,\”recipients\”:{\”type\”:\”group\”,\”id\”:\”0f710b4e-99d8-4b59-b793-a5db290df77f\”},\”stockWeightCode\”:\”100UNCOAT\”,\”mailClassCode\”:\”First\”,\”isDuplex\”:true,\”isAdmail\”:true,\”isConfidential\”:true},\”templateId\”:101}”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/campaigns” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“campaign”:{“name”:”Spring Campaign (Template)”,”pageSize”:”A4 Letter”,”pageOrientation”:”Portrait”,”windowGummedCode”:”C5″,”defaultRecipientName”:”Customer”,”recipients”:{“type”:”group”,”id”:”0f710b4e-99d8-4b59-b793-a5db290df77f”},”stockWeightCode”:”100UNCOAT”,”mailClassCode”:”First”,”isDuplex”:true,”isAdmail”:true,”isConfidential”:true},”templateId”:101}’
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/campaigns” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“campaign”:{“name”:”Spring Campaign (Template)”,”pageSize”:”A4 Letter”,”pageOrientation”:”Portrait”,”windowGummedCode”:”C5″,”defaultRecipientName”:”Customer”,”recipients”:{“type”:”group”,”id”:”0f710b4e-99d8-4b59-b793-a5db290df77f”},”stockWeightCode”:”100UNCOAT”,”mailClassCode”:”First”,”isDuplex”:true,”isAdmail”:true,”isConfidential”:true},”templateId”:101}’
JSON Request Body: Mode A (Use Existing Template Design)
Use this mode when the campaign content is based on a template previously created and saved within the Frankk platform. Pass a valid `templateId` obtained from the `GET /api/v1/template` endpoint. The template defines the visual layout; the `campaign` object supplies print, postage, and recipient settings. No `pdf` object is needed.
{
"campaign": {
"name": "Spring Campaign (Template)",
"pageSize": "A4 Letter",
"pageOrientation": "Portrait",
"windowGummedCode": "C5",
"defaultRecipientName": "Customer",
"recipients": {
"type": "group",
"id": "0f710b4e-99d8-4b59-b793-a5db290df77f"
},
"stockWeightCode": "100UNCOAT",
"mailClassCode": "First",
"isDuplex": true,
"isAdmail": true,
"isConfidential": true
},
"templateId": 101
}
cURL Request Example – Mode B (Create from PDF URL via `pdf.fileUrl`)
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/campaigns” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d “{\”campaign\”:{\”name\”:\”Spring Campaign (PDF URL)\”,\”pageSize\”:\”A4 Letter\”,\”pageOrientation\”:\”Portrait\”,\”windowGummedCode\”:\”C5\”,\”stockWeightCode\”:\”100UNCOAT\”,\”mailClassCode\”:\”First\”,\”isDuplex\”:true,\”isAdmail\”:false,\”isConfidential\”:false},\”pdf\”:{\”fileUrl\”:\”https://example.com/files/spring-campaign.pdf\”,\”originalName\”:\”spring-campaign.pdf\”,\”fileName\”:\”spring-campaign.pdf\”},\”templateName\”:\”Spring Campaign Imported Template\”}”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/campaigns” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“campaign”:{“name”:”Spring Campaign (PDF URL)”,”pageSize”:”A4 Letter”,”pageOrientation”:”Portrait”,”windowGummedCode”:”C5″,”stockWeightCode”:”100UNCOAT”,”mailClassCode”:”First”,”isDuplex”:true,”isAdmail”:false,”isConfidential”:false},”pdf”:{“fileUrl”:”https://example.com/files/spring-campaign.pdf”,”originalName”:”spring-campaign.pdf”,”fileName”:”spring-campaign.pdf”},”templateName”:”Spring Campaign Imported Template”}’
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/campaigns” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“campaign”:{“name”:”Spring Campaign (PDF URL)”,”pageSize”:”A4 Letter”,”pageOrientation”:”Portrait”,”windowGummedCode”:”C5″,”stockWeightCode”:”100UNCOAT”,”mailClassCode”:”First”,”isDuplex”:true,”isAdmail”:false,”isConfidential”:false},”pdf”:{“fileUrl”:”https://example.com/files/spring-campaign.pdf”,”originalName”:”spring-campaign.pdf”,”fileName”:”spring-campaign.pdf”},”templateName”:”Spring Campaign Imported Template”}’
JSON Request Body: Mode B (Create from PDF URL)
Use this mode when the campaign document is a ready-made PDF hosted at a publicly reachable URL. The API downloads the file from `pdf.fileUrl` during processing. Provide `templateName` to save the imported content as a reusable template for future campaigns. No `templateId` is needed.
{
"campaign": {
"name": "Spring Campaign (PDF URL)",
"pageSize": "A4 Letter",
"pageOrientation": "Portrait",
"windowGummedCode": "C5",
"stockWeightCode": "100UNCOAT",
"mailClassCode": "First",
"isDuplex": true,
"isAdmail": false,
"isConfidential": false
},
"pdf": {
"fileUrl": "https://example.com/files/spring-campaign.pdf",
"originalName": "spring-campaign.pdf",
"fileName": "spring-campaign.pdf"
},
"templateName": "Spring Campaign Imported Template"
}
cURL Request Example: Mode C (Create from PDF Base64 via `pdf.fileBase64`)
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/campaigns” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d “{\”campaign\”:{\”name\”:\”Spring Campaign (PDF Base64)\”,\”pageSize\”:\”A4 Letter\”,\”pageOrientation\”:\”Portrait\”,\”windowGummedCode\”:\”C5\”,\”stockWeightCode\”:\”100UNCOAT\”,\”mailClassCode\”:\”First\”,\”isDuplex\”:true,\”isAdmail\”:false,\”isConfidential\”:true},\”pdf\”:{\”fileBase64\”:\”JVBERi0xLjQKJcfs…<truncated-base64-pdf>…\”,\”originalName\”:\”spring-campaign.pdf\”,\”fileName\”:\”spring-campaign.pdf\”},\”templateName\”:\”Spring Campaign Base64 Template\”}”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/campaigns” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“campaign”:{“name”:”Spring Campaign (PDF Base64)”,”pageSize”:”A4 Letter”,”pageOrientation”:”Portrait”,”windowGummedCode”:”C5″,”stockWeightCode”:”100UNCOAT”,”mailClassCode”:”First”,”isDuplex”:true,”isAdmail”:false,”isConfidential”:true},”pdf”:{“fileBase64″:”JVBERi0xLjQKJcfs…<truncated-base64-pdf>…”,”originalName”:”spring-campaign.pdf”,”fileName”:”spring-campaign.pdf”},”templateName”:”Spring Campaign Base64 Template”}’
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/campaigns” -H “Content-Type: application/json” -H “Authorization: Bearer <access-token>” -d ‘{“campaign”:{“name”:”Spring Campaign (PDF Base64)”,”pageSize”:”A4 Letter”,”pageOrientation”:”Portrait”,”windowGummedCode”:”C5″,”stockWeightCode”:”100UNCOAT”,”mailClassCode”:”First”,”isDuplex”:true,”isAdmail”:false,”isConfidential”:true},”pdf”:{“fileBase64″:”JVBERi0xLjQKJcfs…<truncated-base64-pdf>…”,”originalName”:”spring-campaign.pdf”,”fileName”:”spring-campaign.pdf”},”templateName”:”Spring Campaign Base64 Template”}’
JSON Request Body: Mode C (Create from PDF Base64)
Use this mode when the campaign document is generated or stored locally in the client application. Encode the full PDF file as a Base64 string and pass it in `pdf.fileBase64`. This is the recommended approach for server-to-server integrations where the PDF is produced dynamically (for example, from an invoice or letter-generation system). Provide `templateName` to save the uploaded content as a reusable template. No `templateId` or `pdf.fileUrl` is needed.
{
"campaign": {
"name": "Spring Campaign (PDF Base64)",
"pageSize": "A4 Letter",
"pageOrientation": "Portrait",
"windowGummedCode": "C5",
"stockWeightCode": "100UNCOAT",
"mailClassCode": "First",
"isDuplex": true,
"isAdmail": false,
"isConfidential": true
},
"pdf": {
"fileBase64": "JVBERi0xLjQKJcfs......",
"originalName": "spring-campaign.pdf",
"fileName": "spring-campaign.pdf"
},
"templateName": "Spring Campaign Base64 Template"
}
Copied!
Response
HTTP/1.1 200 OK
{
"success": true,
"message": "Campaign created successfully.",
"data": {
"campaignId": "b9c32de3-4f19-4ea8-a273-b2c7d5df42f2",
"templateId": 101,
"status": "Preview",
"warnings": [],
"messages": ["Campaign successfully created."]
},
"errors": null
}
HTTP/1.1 200 OK (Draft — no recipients linked yet)
{
"success": true,
"message": "Campaign created successfully.",
"data": {
"campaignId": "b9c32de3-4f19-4ea8-a273-b2c7d5df42f2",
"templateId": 101,
"status": "Draft",
"warnings": ["Campaign has no recipients yet; staying in Draft."],
"messages": ["Campaign successfully created."]
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Invalid request",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "campaign is required",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "campaign.name is required",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Supported StockWeight values: 100UNCOAT, 120UNCOAT, 250SILK, 300GLOSS, 350SILK, 350UNCOAT",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Supported Mail Class values: First, Second",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "recipients.type must be 'group' or 'single'.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Provide templateId or pdf.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "Empty or invalid PDF.",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Template with id=101 not found.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Group not found.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Recipient not found.",
"data": null,
"errors": null
}
HTTP/1.1 413 Payload Too Large
{
"success": false,
"message": "PDF too large (>100MB).",
"data": null,
"errors": null
}
HTTP/1.1 422 Unprocessable Entity
{
"success": false,
"message": "No layout defined for A4 Letter/Portrait/N/A",
"data": null,
"errors": null
}
HTTP/1.1 422 Unprocessable Entity
{
"success": false,
"message": "Requested campaign settings do not match the template's settings.",
"data": null,
"errors": null
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An error occurred. Please try again later.",
"data": null,
"errors": null
}
Request Schema:
CreateCampaignRequest {
campaign: CampaignDto,
templateId?: number,
pdf?: IncomingPdf,
templateName?: string
}
Response Schema: ApiResponse<CreateCampaignResponse>
Response DTO:
CreateCampaignResponse {
CampaignId,
TemplateId,
Status,
Warnings,
Messages
}
Next Step:
Use returned `campaignId` with `/api/v1/campaigns/{campaignId}`, `/api/v1/campaigns/{campaignId}/preview`, and `/api/v1/campaigns/approve`.
GET /api/v1/campaigns returns a paginated list of campaigns for the authenticated account. Use campaignId values from this response with campaign detail, preview, approve, voucher, cost, schedule, status, and delete endpoints.
This is the main listing endpoint for dashboards and campaign tables.
Authorization
Bearer access token.
sortField
Sort field (for example: updateddate, createddate). Default is updateddate.
sortOrder
Sort order (`ascending` or `descending`). Default is descending.
offset
Number of records to skip. Default is 0.
limit
Number of records to return. Default is 50.
Campaign list returned.
Invalid query values (for example: companyId is not a valid GUID).
Missing or invalid authentication token, or CompanyId claim is missing/invalid.
Unexpected server error.
Request
cURL Request Example:
Windows cmd:
curl -X GET “{{baseUrl}}/api/v1/campaigns?sortField=updateddate&sortOrder=descending&offset=0&limit=50” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X GET “{{baseUrl}}/api/v1/campaigns?sortField=updateddate&sortOrder=descending&offset=0&limit=50” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X GET “{{baseUrl}}/api/v1/campaigns?sortField=updateddate&sortOrder=descending&offset=0&limit=50” -H “Authorization: Bearer <access-token>”
Request Example
GET /api/v1/campaigns?sortField=updateddate&sortOrder=descending&offset=0&limit=50
Copied!
Response
Response:
HTTP/1.1 200 OK
{
"success": true,
"message": "Campaign list fetched successfully.",
"data": {
"total": 2,
"offset": 0,
"limit": 50,
"hasMore": false,
"nextOffset": null,
"items": [
{
"campaignId": "b9c32de3-4f19-4ea8-a273-b2c7d5df42f2",
"campaignName": "Spring Campaign",
"status": "Preview",
"currentStatusOrder": 2,
"recipientCount": 150,
"pageSize": "A4 Letter",
"dispatchDate": null,
"totalCost": 0.00,
"createdDate": "2026-03-08T10:00:00Z",
"updatedDate": "2026-03-09T14:30:00Z"
},
{
"campaignId": "a1b2c3d4-5678-90ab-cdef-1234567890ab",
"campaignName": "Winter Promo",
"status": "Scheduled",
"currentStatusOrder": 5,
"recipientCount": 500,
"pageSize": "A5 Postcard",
"dispatchDate": "2026-03-15T00:00:00Z",
"totalCost": 250.00,
"createdDate": "2026-02-20T09:00:00Z",
"updatedDate": "2026-03-05T16:45:00Z"
}
]
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "companyId is not a valid GUID.",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "Claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": null
}
Request Schema: None (Authorization header required; optional query: sortField, sortOrder, offset, limit)
Response Schema: ApiResponse<PagedResult<CampaignListDto>>
Response DTO:
PagedResult {
Total,
Offset,
Limit,
HasMore,
NextOffset,
Items: List
}
CampaignListDto {
CampaignId,
CampaignName,
Status,
CurrentStatusOrder,
RecipientCount,
PageSize,
DispatchDate,
TotalCost,
CreatedDate,
UpdatedDate
}
Return Value Details:
– success (boolean): `true` when campaign list is returned; `false` on validation or authorization failures.
– message (string): Human-readable result summary such as `Campaign list fetched successfully.`
– data (PagedResult<CampaignListDto> | null): Paginated campaign payload on success; `null` on failure.
– errors (array<string> | null): Optional error details.
Next Step:
Use any `campaignId` in details/preview/approve/cost/schedule endpoints.
Returns all available campaign parameters such as page sizes, orientations, outer codes, mail classes, stock weights, and recipient fields.
Authorization
Bearer token
Campaign parameters fetched successfully.
Invalid Request
Claim missing or invalid.
Unexpected server error.
Request
Windows cmd:
curl -X GET “{{BASEURL}}/api/v1/campaigns/parameters” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X GET “{{BASEURL}}/api/v1/campaigns/parameters” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X GET “{{BASEURL}}/api/v1/campaigns/parameters” -H “Authorization: Bearer <access-token>”
Request Example:
GET /api/v1/campaigns/parameters
Copied!
Response
HTTP/1.1 200 OK
{
“success”: true,
“message”: “Campaign parameters fetched successfully.”,
“data”: {
“pageOrientations”: [“Landscape”, “Portrait”],
“pageSizes”: [“A4 Letter”, “A5 Postcard”],
“outerCodes”: [“C4WIN”, “C5NONWINDOW”, “C5WIN”],
“mailClasses”: [“First”, “Standard”],
“stockWeights”: [“100UNCOAT”, “120UNCOAT”],
“recipientFields”: [“Title”, “FirstName”, “LastName”]
},
“errors”: null
}
HTTP/1.1 400 Bad Request
{
“success”: false,
“message”: “Invalid request.”,
“data”: null,
“errors”: null
}
HTTP/1.1 401 Unauthorized
{
“success”: false,
“message”: “Claim missing or invalid.”,
“data”: null,
“errors”: null
}
HTTP/1.1 500 Internal Server Error
{
“success”: false,
“message”: “An unexpected error occurred.”,
“data”: null,
“errors”: null
}
Returns available campaign configurations including page size, orientation, and valid combinations for campaign creation.
Authorization
Bearer access token
pageSize
Filter configurations by page size (e.g. A4 Letter)
orientation
Filter by page orientation (Portrait / Landscape)
Unexpected server error.
Request
Windows cmd:
curl -X GET “{{BASEURL}}/api/v1/campaigns/configurations?pageSize=A4 Letter&orientation=Portrait” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X GET “{{BASEURL}}/api/v1/campaigns/configurations?pageSize=A4 Letter&orientation=Portrait” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X GET “{{BASEURL}}/api/v1/campaigns/configurations?pageSize=A4 Letter&orientation=Portrait” -H “Authorization: Bearer <access-token>”
Request Example:
GET /api/v1/campaigns/configurations?pageSize=A4 Letter&orientation=Portrait
Copied!
Response
HTTP/1.1 200 OK
{
“success”: true,
“message”: “Campaign configurations fetched successfully.”,
“data”: [
{
“name”: “A4 Letter Portrait C5WIN”,
“pageSize”: “A4 Letter”,
“pageOrientation”: “Portrait”,
“windowGummedCode”: “C5WIN”,
“validCombinations”: [
{
“stockWeightCode”: “100UNCOAT”,
“isDuplex”: true,
“mailClassCode”: “Standard”,
“isAdmail”: true,
“isConfidential”: false
}
]
}
],
“errors”: null
}
HTTP/1.1 400 Bad Request
{
“success”: false,
“message”: “Invalid pageSize or orientation value.”,
“data”: null,
“errors”: null
}
HTTP/1.1 401 Unauthorized
{
“success”: false,
“message”: “Claim missing or invalid.”,
“data”: null,
“errors”: null
}
HTTP/1.1 500 Internal Server Error
{
“success”: false,
“message”: “An unexpected error occurred.”,
“data”: null,
“errors”: null
}
GET /api/v1/campaigns/{campaignId} returns full details for one campaign. Use campaignId from Create Campaign or List Campaigns.
Use this endpoint to confirm current campaign settings before approval or scheduling.
Authorization
Bearer access token.
campaignId
Campaign identifier.
Campaign details returned.
Invalid request (for example: companyId is not a valid GUID).
Missing or invalid authentication token, or CompanyId claim is missing/invalid.
Campaign not found or does not belong to the authenticated company.
Unexpected server error.
Request
cURL Request Example:
Windows cmd:
curl -X GET “{{baseUrl}}/api/v1/campaigns/b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X GET “{{baseUrl}}/api/v1/campaigns/b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X GET “{{baseUrl}}/api/v1/campaigns/b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
Request Example:
GET /api/v1/campaigns/b9c32de3-4f19-4ea8-a273-b2c7d5df42f2
JSON Request Body:
No request body is required.
Copied!
Response
Response
HTTP/1.1 200 OK
{
"success": true,
"message": "Campaign details fetched successfully.",
"data": {
"id": "b9c32de3-4f19-4ea8-a273-b2c7d5df42f2",
"name": "Spring Campaign",
"status": "Preview",
"recipientCount": 150,
"dispatchDate": null,
"created": "2026-03-08T10:00:00Z",
"updated": "2026-03-09T14:30:00Z",
"cost": 0.00,
"pageSize": "A4 Letter",
"pageOrientation": "Portrait",
"mailClass": "First",
"windowsGummedCode": "C5WIN"
},
"errors": null
}
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "companyId is not a valid GUID.",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Campaign not found.",
"data": null,
"errors": null
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": null
}
Request Schema: None (Authorization header required; path parameter: campaignId)
Response Schema: ApiResponse<CampaignDetailsDto>
Response DTO:
CampaignDetailsDto {
Id,
Name,
Status,
RecipientCount,
DispatchDate,
Created,
Updated,
Cost,
PageSize,
PageOrientation,
MailClass,
WindowsGummedCode
}
Return Value Details:
– success (boolean): `true` when campaign details are returned; `false` on validation, authorization, or not-found outcomes.
– message (string): Human-readable result summary such as `Campaign details fetched successfully.` or `Campaign not found.`
– data (CampaignDetailsDto | null): Campaign payload on success; `null` on failure.
– errors (array<string> | null): Optional error details.
Next Step:
If content looks correct, call `/api/v1/campaigns/{campaignId}/preview` and then `/api/v1/campaigns/approve`.
GET /api/v1/campaigns/{campaignId}/preview returns the campaign preview PDF file. Use `campaignId` from Create Campaign or List Campaigns.
Use this endpoint to verify visual output before approving and scheduling.
Note: A successful response returns the raw PDF binary stream with `Content-Type: application/pdf`. There is no JSON wrapper on success. Save the response body directly as a .pdf file.
Authorization
Bearer access token.
campaignId
Campaign identifier.
Preview file returned (application/pdf).
Invalid request (for example: companyId is not a valid GUID).
Missing or invalid authentication token, or CompanyId/UserId claim is missing/invalid.
Campaign preview file not found or does not exist on server.
Unexpected server error.
Request
cURL Request Example:
Windows cmd:
curl -X GET “{{baseUrl}}/api/v1/campaigns/b9c32de3-4f19-4ea8-a273-b2c7d5df42f2/preview” -H “Authorization: Bearer ” –output preview.pdf
PowerShell:
Invoke-WebRequest -Uri “{{baseUrl}}/api/v1/campaigns/b9c32de3-4f19-4ea8-a273-b2c7d5df42f2/preview” -Headers @{ Authorization = “Bearer ” } -OutFile preview.pdf
Linux/macOS:
curl -X GET “{{baseUrl}}/api/v1/campaigns/b9c32de3-4f19-4ea8-a273-b2c7d5df42f2/preview” -H “Authorization: Bearer ” -o preview.pdf
Request Example:
GET /api/v1/campaigns/b9c32de3-4f19-4ea8-a273-b2c7d5df42f2/preview
JSON Request Body:
No request body is required.
Copied!
Response
Response
HTTP/1.1 200 OK
Content-Type: application/pdf
Content-Disposition: attachment; filename=”campaign-preview.pdf”
<<< binary PDF file >>>
HTTP/1.1 400 Bad Request
{
"success": false,
"message": "companyId is not a valid GUID.",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized (variant)
{
"success": false,
"message": "UserId claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Preview file not found for this campaign.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found (variant)
{
"success": false,
"message": "Preview file does not exist on server.",
"data": null,
"errors": null
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": null
}
JSON Response Body:
Success: No JSON body — raw PDF binary stream.
Error: Standard ApiResponseJSON wrapper.
Request Schema: None (Authorization header required; path parameter: campaignId)
Response Schema (success): application/pdf binary file
Response Schema (error): ApiResponse<object>
Return Value Details:
– On 200 OK: Binary PDF file streamed directly. Save using file output flag (e.g., `–output` or `-o` in cURL, `-OutFile` in PowerShell).
– On error: Standard JSON wrapper with `success`, `message`, `data` (null), `errors`.
Next Step:
If preview looks correct, proceed to `/api/v1/campaigns/approve`.
POST /api/v1/campaigns/approve moves a campaign to approved state when business rules are met. Use this endpoint before voucher, cost confirmation, and schedule.
Approval is a prerequisite for voucher actions, final cost confirmation, and scheduling.
Authorization
Bearer access token.
campaignId
Campaign identifier from Create/List endpoints.
Request processed. Includes approval success confirmation or a business-rule message explaining why approval was not possible.
Missing or invalid authentication token, or CompanyId claim is missing/invalid.
Campaign not found or does not belong to the authenticated company.
Unexpected server error.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/campaigns/approve?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/campaigns/approve?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/campaigns/approve?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
Request Example:
POST /api/v1/campaigns/approve?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2
JSON Request Body:
No request body is required.
Copied!
Response
Response:
HTTP/1.1 200 OK (success)
{
"success": true,
"message": "Campaign approved successfully.",
"data": {
"currentStatus": "Approved"
},
"errors": null
}
HTTP/1.1 200 OK (read-only state)
{
"success": true,
"message": "Unable to approve the campaign because it is currently in a read-only state.",
"data": null,
"errors": null
}
HTTP/1.1 200 OK (invalid status transition)
{
"success": true,
"message": "Cannot promote status: the requested status is not valid for this campaign.",
"data": null,
"errors": null
}
HTTP/1.1 200 OK (no recipients)
{
"success": true,
"message": "Cannot approve the campaign. Please add at least one recipient before approving.",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Approval failed: the campaign could not be found.",
"data": null,
"errors": null
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": null
}
Request Schema: None (Authorization header required; query parameter: campaignId)
Response Schema (success): ApiResponse<object> containing `{ currentStatus }`.
Response Schema (business-rule): ApiResponse<object> with descriptive message and `data: null`.
Return Value Details:
– success (boolean): `true` when the request was processed (even if business rules blocked approval).
– message (string): Human-readable result such as `Campaign approved successfully.` or a business-rule explanation.
– data (object | null): On approval success, contains `{ currentStatus: “<new status>” }`. On business-rule message, `null`.
– errors (array<string> | null): Optional error details.
Next Step:
After approval, optionally call `/api/v1/campaigns/voucher` to apply a voucher, then `/api/v1/campaigns/cost` and `/api/v1/campaigns/schedule`.
POST /api/v1/campaigns/voucher applies or removes a voucher for an approved campaign. Voucher updates affect cost and schedule outcomes.
Use this endpoint after approval and before final scheduling.
Authorization
Bearer access token.
campaignId
Campaign identifier.
VoucherAction
Allowed values: `apply`, `remove`.
VoucherCode
Conditionally required – Required when `VoucherAction=apply`.
Request processed. Includes updated cost details on success, or a business-rule message explaining why the voucher action could not be completed.
Invalid or missing voucher action/code input.
Missing or invalid authentication token, or CompanyId claim is missing/invalid.
Campaign not found or does not belong to the authenticated company.
Unexpected server error.
Request
cURL Request Example:
Windows cmd (apply voucher):
curl -X POST “{{baseUrl}}/api/v1/campaigns/voucher?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&VoucherAction=apply&VoucherCode=SAVE20” -H “Authorization: Bearer <access-token>”
Windows cmd (remove voucher):
curl -X POST “{{baseUrl}}/api/v1/campaigns/voucher?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&VoucherAction=remove” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/campaigns/voucher?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&VoucherAction=apply&VoucherCode=SAVE20” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/campaigns/voucher?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&VoucherAction=apply&VoucherCode=SAVE20” -H “Authorization: Bearer <access-token>”
Request Example:
POST /api/v1/campaigns/voucher?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&VoucherAction=apply&VoucherCode=SAVE20
JSON Request Body:
No request body is required.
Copied!
Response
Response:
HTTP/1.1 200 OK (voucher applied successfully)
{
"success": true,
"message": "Successful!",
"data": {
"mailClass": "First",
"stockweight": "120UNCOAT",
"isAdmail": false,
"isConfidential": false,
"isDuplex": false,
"isTabbed": false,
"scheduledDate": "2026-04-15T00:00:00",
"estimatedDeliveryDate": "2026-04-17T00:00:00",
"voucherCode": "SAVE20",
"productCode": "PRODCODE01",
"totalRecipients": 150,
"currencyCode": "GBP",
"costPerRecipient": 0.55,
"subtotal": 82.50,
"discountAmount": 16.50,
"vatAmount": 13.20,
"totalCost": 79.20
},
"errors": null
}
HTTP/1.1 200 OK (voucher removed successfully)
{
"success": true,
"message": "Successful!",
"data": {
"mailClass": "First",
"stockweight": "120UNCOAT",
"isAdmail": false,
"isConfidential": false,
"isDuplex": false,
"isTabbed": false,
"scheduledDate": "2026-04-15T00:00:00",
"estimatedDeliveryDate": "2026-04-17T00:00:00",
"voucherCode": "",
"productCode": "PRODCODE01",
"totalRecipients": 150,
"currencyCode": "GBP",
"costPerRecipient": 0.55,
"subtotal": 82.50,
"discountAmount": 0.00,
"vatAmount": 16.50,
"totalCost": 99.00
},
"errors": null
}
HTTP/1.1 200 OK (read-only state)
{
"success": true,
"message": "Campaign is currently in a read-only state.",
"data": null,
"errors": null
}
HTTP/1.1 200 OK (not approved)
{
"success": true,
"message": "Approve the campaign to apply the voucher",
"data": null,
"errors": null
}
HTTP/1.1 200 OK (invalid voucher code)
{
"success": true,
"message": "Unsuccessful! Voucher code is not valid",
"data": null,
"errors": null
}
HTTP/1.1 200 OK (no recipients)
{
"success": true,
"message": "Can not apply voucher. Please add at least one recipient before approving.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (missing action)
{
"success": false,
"message": "Voucher action must be declared.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (invalid action)
{
"success": false,
"message": "Voucher action is invalid.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (missing code)
{
"success": false,
"message": "Voucher code must be provide to apply the voucher.",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "campaign not found.",
"data": null,
"errors": null
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": null
}
Request Schema: None (Authorization header required; query parameters: campaignId, VoucherAction, VoucherCode)
Response Schema (success): ApiResponse<CampaignCostDetailsVM>
Response Schema (business-rule): ApiResponse<object> with descriptive message and `data: null`.
Response DTO:
CampaignCostDetailsVM {
MailClass,
Stockweight,
IsAdmail,
IsConfidential,
IsDuplex,
IsTabbed,
ScheduledDate,
EstimatedDeliveryDate,
VoucherCode,
ProductCode,
TotalRecipients,
CurrencyCode,
CostPerRecipient,
Subtotal,
DiscountAmount,
VatAmount,
TotalCost
}
Return Value Details:
– success (boolean): `true` when the request was processed.
– message (string): `Successful!` on success, or a business-rule explanation string.
– data (CampaignCostDetailsVM | null): Updated cost breakdown on success; `null` on business-rule messages.
– errors (array<string> | null): Optional error details.
Next Step:
Call `/api/v1/campaigns/cost` to review latest totals, then proceed to `/api/v1/campaigns/schedule`.
POST /api/v1/campaigns/cost returns pricing details for a campaign using current or overridden options. Use this endpoint to review payable amounts before scheduling.
Use this endpoint as the final pricing check before scheduling.
Authorization
Bearer access token.
campaignId
Campaign identifier.
stockWeight
Optional stock override.
mailClass
Optional mail class override.
isAdMail
`true` or `false`.
isConfidential
`true` or `false`.
isDuplex
`true` or `false`.
Cost request processed. Returns cost breakdown on success, or a business-rule message explaining why cost details are unavailable.
Invalid query values (boolean format, unsupported stock weight, mail class, admail, confidential, or duplex option).
Missing or invalid authentication token, or CompanyId claim is missing/invalid.
Campaign not found or does not belong to the authenticated company.
Unexpected server error.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/campaigns/cost?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&isAdMail=false&isConfidential=false&isDuplex=false” -H “Authorization: Bearer <access-token>”
Windows cmd (with optional overrides):
curl -X POST “{{baseUrl}}/api/v1/campaigns/cost?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&stockWeight=120UNCOAT&mailClass=First&isAdMail=false&isConfidential=false&isDuplex=false” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/campaigns/cost?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&isAdMail=false&isConfidential=false&isDuplex=false” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/campaigns/cost?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&isAdMail=false&isConfidential=false&isDuplex=false” -H “Authorization: Bearer <access-token>”
Request Example:
POST /api/v1/campaigns/cost?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&stockWeight=120UNCOAT&mailClass=First&isAdMail=false&isConfidential=false&isDuplex=false
JSON Request Body:
No request body is required.
Copied!
Response
Response:
HTTP/1.1 200 OK (success)
{
"success": true,
"message": "Successful!",
"data": {
"mailClass": "First",
"stockweight": "120UNCOAT",
"isAdmail": false,
"isConfidential": false,
"isDuplex": false,
"isTabbed": false,
"scheduledDate": "2026-04-15T00:00:00",
"estimatedDeliveryDate": "2026-04-17T00:00:00",
"voucherCode": "SAVE20",
"productCode": "PRODCODE01",
"totalRecipients": 150,
"currencyCode": "GBP",
"costPerRecipient": 0.55,
"subtotal": 82.50,
"discountAmount": 16.50,
"vatAmount": 13.20,
"totalCost": 79.20
},
"errors": null
}
HTTP/1.1 200 OK (read-only state)
{
"success": true,
"message": "Cost details unavailable — because it is currently in a read-only state.",
"data": null,
"errors": null
}
HTTP/1.1 200 OK (not approved)
{
"success": true,
"message": "Cost details unavailable - please approve the campaign first.",
"data": null,
"errors": null
}
HTTP/1.1 200 OK (no recipients)
{
"success": true,
"message": "Cost details unavailable. Please add at least one recipient before approving.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (invalid boolean - isAdMail)
{
"success": false,
"message": "isAdMail is invalid.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (invalid boolean - isConfidential)
{
"success": false,
"message": "isConfidential is invalid.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (invalid boolean - isDuplex)
{
"success": false,
"message": "isDuplex is invalid.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (unsupported stock weight)
{
"success": false,
"message": "Supported StockWeight values: 100UNCOAT, 120UNCOAT, 250SILK, 300GLOSS, 350SILK, 350UNCOAT",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (unsupported mail class)
{
"success": false,
"message": "Supported Mail Class values: First, Second",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (unsupported admail option)
{
"success": false,
"message": "Supported Admail values: true, false",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (unsupported confidential option)
{
"success": false,
"message": "Supported Confidential values: true, false",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (unsupported duplex option)
{
"success": false,
"message": "Supported Confidential values: true, false",
"data": null,
"errors": null
}
Note: The 400 responses for unsupported stock weight, mail class, admail, confidential, and duplex include lists of accepted values based on the campaign’s supported format. The example messages above are illustrative — actual values will vary.
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Cost details unavailable — campaign not found.",
"data": null,
"errors": null
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": null
}
Request Schema: None (Authorization header required; query parameters: campaignId, isAdMail, isConfidential, isDuplex; optional: stockWeight, mailClass)
Response Schema (success): ApiResponse<CampaignCostDetailsVM>
Response Schema (business-rule): ApiResponse<object> with descriptive message and `data: null`.
Response DTO:
CampaignCostDetailsVM {
MailClass,
Stockweight,
IsAdmail,
IsConfidential,
IsDuplex,
IsTabbed,
ScheduledDate,
EstimatedDeliveryDate,
VoucherCode,
ProductCode,
TotalRecipients,
CurrencyCode,
CostPerRecipient,
Subtotal,
DiscountAmount,
VatAmount,
TotalCost
}
Return Value Details:
– success (boolean): `true` when the request was processed.
– message (string): `Successful!` on cost retrieval success, or a business-rule/validation explanation.
– data (CampaignCostDetailsVM | null): Full cost breakdown on success; `null` on business-rule messages.
– errors (array<string> | null): Optional error details.
– MailClass (string): Mail class used for cost calculation (e.g., `First`, `Second`).
– Stockweight (string): Stock weight code used.
– IsAdmail (boolean): Whether admail pricing applies.
– IsConfidential (boolean): Whether confidential handling applies.
– IsDuplex (boolean): Whether duplex printing applies.
– IsTabbed (boolean): Whether tabbed format applies.
– ScheduledDate (datetime): The schedule date used for cost calculation.
– EstimatedDeliveryDate (datetime): Estimated delivery date based on schedule and mail class.
– VoucherCode (string): Applied voucher code, or empty string if none.
– ProductCode (string): Internal product code.
– TotalRecipients (integer): Number of recipients.
– CurrencyCode (string): Currency code (e.g., `GBP`).
– CostPerRecipient (decimal): Cost per individual recipient.
– Subtotal (decimal): Pre-discount subtotal.
– DiscountAmount (decimal): Voucher discount amount.
– VatAmount (decimal): VAT amount.
– TotalCost (decimal): Final payable total.
Next Step:
Use `ScheduledDate` and totals to continue with `/api/v1/campaigns/schedule`.
POST /api/v1/campaigns/availableDates returns available campaign schedule dates in a date range. Use these dates as input to /api/v1/campaigns/schedule.
This endpoint helps identify selectable dates.
Authorization
Bearer access token.
start
Start date in `yyyy-MM-dd`. Defaults to today.
end
End date in `yyyy-MM-dd`. Defaults to today + 30 days.
Available dates returned.
Invalid date format for start or end parameter.
Missing or invalid authentication token, or CompanyId claim is missing/invalid.
Unexpected server error.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/campaigns/availableDates?start=2026-04-01&end=2026-04-30” -H “Authorization: Bearer ”
Windows cmd (defaults — today to today + 30 days):
curl -X POST “{{baseUrl}}/api/v1/campaigns/availableDates” -H “Authorization: Bearer ”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/campaigns/availableDates?start=2026-04-01&end=2026-04-30” -H “Authorization: Bearer ”
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/campaigns/availableDates?start=2026-04-01&end=2026-04-30” -H “Authorization: Bearer ”
Request Example:
POST /api/v1/campaigns/availableDates?start=2026-04-01&end=2026-04-30
JSON Request Body:
No request body is required.
Copied!
Response
Response
HTTP/1.1 200 OK
{
"success": true,
"message": "Successful!",
"data": [
"2026-04-02",
"2026-04-03",
"2026-04-06",
"2026-04-07",
"2026-04-08",
"2026-04-09",
"2026-04-10",
"2026-04-13",
"2026-04-14",
"2026-04-15"
],
"errors": null
}
HTTP/1.1 400 Bad Request (invalid start date)
{
"success": false,
"message": "Invalid start date format. Expected format: yyyy-MM-dd (defaults to today)",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (invalid end date)
{
"success": false,
"message": "Invalid end date format. Expected format: yyyy-MM-dd (defaults to 30 days time)",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": null
}
Request Schema: None (Authorization header required; optional query parameters: start, end in yyyy-MM-dd format)
Response Schema: ApiResponse<List>
Return Value Details:
– success (boolean): `true` when dates are returned successfully.
– message (string): `Successful!` on success, or a date-format validation message.
– data (array | null): List of available dates in `yyyy-MM-dd` format. Excludes weekends and blocked dates. `null` on error.
– errors (array | null): Optional error details.
Next Step:
Pick a date from the returned list and use it as `send_date` in `/api/v1/campaigns/schedule`.
POST /api/v1/campaigns/schedule schedules an approved campaign for dispatch. Use send_date from /api/v1/campaigns/availableDates or enable next_available_date.
This endpoint is typically the final step of campaign setup.
Authorization
Bearer access token.
campaignId
Campaign identifier.
send_date
Requested schedule date in `yyyy-MM-dd`. Defaults to tomorrow.
next_available_date
If true, API uses the next available date at or after `send_date`.
use_balance
`true` to pay by balance; `false` to use provisional booking flow.
Schedule request processed. Returns campaign ID and payment status on success, or a business-rule message explaining why scheduling could not proceed.
Invalid date format, unavailable date, or company lacks provisional booking permission.
Missing or invalid authentication token, or CompanyId claim is missing/invalid.
Campaign not found or does not belong to the authenticated company.
Unexpected server error.
Request
cURL Request Example:
Windows cmd (pay by balance):
curl -X POST “{{baseUrl}}/api/v1/campaigns/schedule?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&send_date=2026-04-15&next_available_date=false&use_balance=true” -H “Authorization: Bearer <access-token>”
Windows cmd (provisional booking):
curl -X POST “{{baseUrl}}/api/v1/campaigns/schedule?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&send_date=2026-04-15&next_available_date=true&use_balance=false” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/campaigns/schedule?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&send_date=2026-04-15&next_available_date=false&use_balance=true” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/campaigns/schedule?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&send_date=2026-04-15&next_available_date=false&use_balance=true” -H “Authorization: Bearer <access-token>”
Request Example:
POST /api/v1/campaigns/schedule?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2&send_date=2026-04-15&next_available_date=false&use_balance=true
JSON Request Body:
No request body is required.
Copied!
Response
Response:
HTTP/1.1 200 OK (balance payment — success)
{
"success": true,
"message": "Congratulations! Your payment was successful. Campaign scheduled successfully!",
"data": {
"campaignId": "b9c32de3-4f19-4ea8-a273-b2c7d5df42f2",
"paymentStatus": "ACCEPTED"
},
"errors": null
}
HTTP/1.1 200 OK (provisional booking — success)
{
"success": true,
"message": "Congratulations! Provisional booking was succesful.",
"data": {
"campaignId": "b9c32de3-4f19-4ea8-a273-b2c7d5df42f2",
"orderId": "ORD-20260415-001",
"paymentStatus": "PENDING"
},
"errors": null
}
HTTP/1.1 200 OK (read-only state)
{
"success": true,
"message": "Can not schedule campaign. Campaign is currently in a read-only state.",
"data": null,
"errors": null
}
HTTP/1.1 200 OK (not approved)
{
"success": true,
"message": "Can not schedule campaign. Please approve the campaign first.",
"data": null,
"errors": null
}
HTTP/1.1 200 OK (balance locked)
{
"success": true,
"message": "Can not schedule campaign. Company Balance is locked.",
"data": null,
"errors": null
}
HTTP/1.1 200 OK (payment failed)
{
"success": true,
"message": "Can not schedule campaign. Something went wrong.",
"data": null,
"errors": null
}
HTTP/1.1 200 OK (no recipients)
{
"success": true,
"message": "Cost details unavailable. Please add at least one recipient before approving.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (invalid date format)
{
"success": false,
"message": "Invalid send_date format. Expected format: yyyy-MM-dd (defaults to tomorrow)",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (no dates available from given date)
{
"success": false,
"message": "No available dates found from 2026-04-15 onwards.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (selected date not available)
{
"success": false,
"message": "The selected date 2026-04-15 is not available for scheduling.",
"data": null,
"errors": null
}
HTTP/1.1 400 Bad Request (no provisional permission)
{
"success": false,
"message": "Company does not have provisional booking permission.",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Can not schedule campaign. campaign not found.",
"data": null,
"errors": null
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": null
}
Request Schema: None (Authorization header required; query parameters: campaignId, next_available_date, use_balance; optional: send_date in yyyy-MM-dd format)
Response Schema (balance success): ApiResponse<object> containing `{ campaignId, paymentStatus: “ACCEPTED” }`.
Response Schema (provisional success): ApiResponse<object> containing `{ campaignId, orderId, paymentStatus: “PENDING” }`.
Response Schema (business-rule): ApiResponse<object> with descriptive message and `data: null`.
Return Value Details:
– success (boolean): `true` when the request was processed.
– message (string): Confirmation or business-rule explanation.
– data (object | null): On success, an object with `campaignId` and `paymentStatus` (and `orderId` for provisional). `null` on business-rule messages.
– errors (array<string> | null): Optional error details.
– campaignId (string/GUID): The scheduled campaign identifier.
– paymentStatus (string): `ACCEPTED` when paid by balance; `PENDING` for provisional booking (invoice will be sent via email).
– orderId (string): Only present for provisional booking. Reference number for the pending payment.
Next Step:
After scheduling, use `/api/v1/campaigns/statusDetails` to track campaign progress.
POST /api/v1/campaigns/statusDetails returns the current status and status history for a campaign. Use this endpoint after approve/schedule to track progress.
Use this endpoint in campaign tracking screens and status timelines.
Authorization
Bearer access token.
campaignId
Campaign identifier.
Status details returned.
Missing or invalid authentication token, or CompanyId claim is missing/invalid.
Campaign not found or does not belong to the authenticated company.
Unexpected server error.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/campaigns/statusDetails?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/campaigns/statusDetails?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/campaigns/statusDetails?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
Request Example:
POST /api/v1/campaigns/statusDetails?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2
JSON Request Body:
No request body is required.
Copied!
Response
Response:
HTTP/1.1 200 OK
{
"success": true,
"message": "Successful!",
"data": {
"currentStatus": "Scheduled",
"statusHistories": [
{
"status": "Draft",
"date": "2026-03-08T10:00:00Z"
},
{
"status": "Preview",
"date": "2026-03-08T10:05:00Z"
},
{
"status": "Approved",
"date": "2026-03-09T14:30:00Z"
},
{
"status": "Scheduled",
"date": "2026-03-10T09:00:00Z"
}
]
},
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "campaign not found.",
"data": null,
"errors": null
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": null
}
Request Schema: None (Authorization header required; query parameter: campaignId)
Response Schema: ApiResponse<CampaignStatusVM>
Response DTO:
CampaignStatusVM {
CurrentStatus,
StatusHistories
}
CampaignStatusHistoryVM {
Status,
Date
}
Return Value Details:
– success (boolean): `true` when status details are returned successfully.
– message (string): `Successful!` on success; error message on failure.
– data (CampaignStatusVM | null): Status payload on success; `null` on failure.
– errors (array<string> | null): Optional error details.
– CurrentStatus (string): The campaign’s current status (e.g., `Draft`, `Preview`, `Approved`, `Scheduled`, `Dispatched`).
– StatusHistories (array<CampaignStatusHistoryVM>): Chronological list of all status transitions.
– Status (string): Status name at that point.
– Date (datetime): Timestamp of the status transition.
POST /api/v1/campaigns/delete deletes a campaign when allowed by current campaign state. Use this endpoint for cleanup of draft or editable campaigns that should not proceed further.
Use this endpoint before scheduling when a campaign should be discarded.
Authorization
Bearer access token.
campaignId
Campaign identifier.
Delete request processed. Returns `true` on success, or a business-rule message explaining why deletion is not allowed.
Missing or invalid authentication token, or CompanyId claim is missing/invalid.
Campaign not found or does not belong to the authenticated company.
Unexpected server error.
Request
cURL Request Example:
Windows cmd:
curl -X POST “{{baseUrl}}/api/v1/campaigns/delete?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
PowerShell:
curl -X POST “{{baseUrl}}/api/v1/campaigns/delete?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
Linux/macOS:
curl -X POST “{{baseUrl}}/api/v1/campaigns/delete?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2” -H “Authorization: Bearer <access-token>”
Request Example:
POST /api/v1/campaigns/delete?campaignId=b9c32de3-4f19-4ea8-a273-b2c7d5df42f2
JSON Request Body:
No request body is required.
Copied!
Response
Response:
HTTP/1.1 200 OK (success)
{
"success": true,
"message": "Campaign deleted successfully.",
"data": true,
"errors": null
}
HTTP/1.1 200 OK (read-only / already scheduled)
{
"success": true,
"message": "Can not delete. Campaign is already scheduled or in a read-only state.",
"data": null,
"errors": null
}
HTTP/1.1 401 Unauthorized
{
"success": false,
"message": "CompanyId claim missing or invalid.",
"data": null,
"errors": null
}
HTTP/1.1 404 Not Found
{
"success": false,
"message": "Cannot delete — campaign not found.",
"data": null,
"errors": null
}
HTTP/1.1 500 Internal Server Error
{
"success": false,
"message": "An unexpected error occurred.",
"data": null,
"errors": null
}
Request Schema: None (Authorization header required; query parameter: campaignId)
Response Schema: ApiResponse<boolean>
Return Value Details:
– success (boolean): `true` when the request was processed.
– message (string): `Campaign deleted successfully.` on success; business-rule explanation otherwise.
– data (boolean | null): `true` when the campaign was deleted; `null` on business-rule messages.
– errors (array<string> | null): Optional error details.
optimise your mailing strategy today