Commission Configuration
Get Affiliate Commission
Retrieve the commission rate configuration for a specific affiliate, including the effective resolved rate.
GET /v1/affiliates/{id}/commission
- Required scope:
affiliates:read
- Rate limit: 120 requests/minute
Path Parameters
| Parameter |
Type |
Description |
id |
integer |
Affiliate ID |
Example Request
curl "api.heldsway.com/api//v1/affiliates/42/commission" \
-H "Authorization: Bearer <access_token>"
Success Response — 200 OK
{
"success": true,
"message": "OK",
"data": {
"affiliate_rate": 10.0,
"business_default_rate": 8.0,
"effective_rate": 10.0
}
}
| Field |
Type |
Description |
affiliate_rate |
float|null |
This affiliate’s individual override rate. null if none is set |
business_default_rate |
float|null |
The business-wide default commission rate |
effective_rate |
float|null |
The rate that will actually be used (affiliate_rate if set, otherwise business_default_rate) |
Error Responses
| Status |
Code |
Description |
404 |
NOT_FOUND |
Affiliate not found |
Set Affiliate Commission
Set or clear the individual commission rate override for an affiliate.
PUT /v1/affiliates/{id}/commission
- Required scope:
affiliates:write
- Rate limit: 60 requests/minute
Path Parameters
| Parameter |
Type |
Description |
id |
integer |
Affiliate ID |
Request Body
| Field |
Type |
Required |
Description |
commission_rate |
float|null |
Yes |
Commission percentage (0–100). Send null to remove the override and revert to the business default |
Example Request — Set override
curl -X PUT "api.heldsway.com/api//v1/affiliates/42/commission" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "commission_rate": 20.0 }'
Example Request — Clear override
curl -X PUT "api.heldsway.com/api//v1/affiliates/42/commission" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "commission_rate": null }'
Success Response — 200 OK
{
"success": true,
"message": "Commission rate updated.",
"data": {
"affiliate_rate": 20.0,
"business_default_rate": 8.0,
"effective_rate": 20.0
}
}
Error Responses
| Status |
Code |
Description |
404 |
NOT_FOUND |
Affiliate not found |
422 |
VALIDATION_ERROR |
commission_rate missing from request body or out of range |
List Commission Rules for Link
List all commission rules attached to a referral link. Rules are returned ordered by priority (highest first), then by creation date.
GET /v1/links/{id}/commission-rules
- Required scope:
affiliates:read
- Rate limit: 120 requests/minute
Path Parameters
| Parameter |
Type |
Description |
id |
integer |
Referral link ID |
Example Request
curl "api.heldsway.com/api//v1/links/10/commission-rules" \
-H "Authorization: Bearer <access_token>"
Success Response — 200 OK
{
"success": true,
"message": "OK",
"data": [
{
"id": 5,
"label": "Black Friday Deal",
"commission_rate": 20.0,
"priority": 10,
"valid_from": "2026-11-28T00:00:00.000000Z",
"valid_until": "2026-11-30T23:59:59.000000Z",
"max_conversions": 100,
"conversion_count": 45,
"is_active": true,
"status": "active",
"created_at": "2026-10-01T09:00:00.000000Z"
},
{
"id": 3,
"label": "Always-on bonus",
"commission_rate": 12.0,
"priority": 0,
"valid_from": null,
"valid_until": null,
"max_conversions": null,
"conversion_count": 312,
"is_active": true,
"status": "active",
"created_at": "2026-03-01T09:00:00.000000Z"
}
]
}
Error Responses
| Status |
Code |
Description |
404 |
NOT_FOUND |
Referral link not found |
Create Commission Rule
Attach a new commission rule to a referral link. Rules allow you to define time-limited promotions, conversion caps, or priority overrides on a per-link basis.
POST /v1/links/{id}/commission-rules
- Required scope:
affiliates:write
- Rate limit: 60 requests/minute
Path Parameters
| Parameter |
Type |
Description |
id |
integer |
Referral link ID |
Request Body
| Field |
Type |
Required |
Constraints |
Description |
commission_rate |
float |
Yes |
0–100 |
Commission percentage this rule applies |
label |
string |
No |
max 255 |
Human-readable name (e.g. "Black Friday") |
priority |
integer |
No |
min 0, default 0 |
Higher value = takes precedence over lower-priority rules |
valid_from |
date/datetime |
No |
— |
Rule activates at this time. Omit for no start restriction |
valid_until |
date/datetime |
No |
must be ≥ valid_from |
Rule expires at this time. Omit for no expiry |
max_conversions |
integer |
No |
min 1 |
Cap on how many conversions this rule applies to. Omit for unlimited |
is_active |
boolean |
No |
default true |
Whether the rule is enabled immediately |
curl -X POST "api.heldsway.com/api//v1/links/10/commission-rules" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"commission_rate": 25.0,
"label": "Launch Week Bonus",
"priority": 5,
"valid_from": "2026-05-01",
"valid_until": "2026-05-07",
"max_conversions": 50
}'
Example Request — Permanent always-on rule
curl -X POST "api.heldsway.com/api//v1/links/10/commission-rules" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"commission_rate": 15.0,
"label": "Base link rate"
}'
Success Response — 201 Created
{
"success": true,
"message": "Created",
"data": {
"id": 8,
"label": "Launch Week Bonus",
"commission_rate": 25.0,
"priority": 5,
"valid_from": "2026-05-01T00:00:00.000000Z",
"valid_until": "2026-05-07T00:00:00.000000Z",
"max_conversions": 50,
"conversion_count": 0,
"is_active": true,
"status": "scheduled",
"created_at": "2026-04-13T10:00:00.000000Z"
}
}
Error Responses
| Status |
Code |
Description |
404 |
NOT_FOUND |
Referral link not found |
422 |
VALIDATION_ERROR |
Invalid fields |
Update Commission Rule
Modify an existing commission rule. Only include fields you want to change.
Note: conversion_count is system-managed and cannot be updated via the API.
PATCH /v1/links/{linkId}/commission-rules/{ruleId}
- Required scope:
affiliates:write
- Rate limit: 60 requests/minute
Path Parameters
| Parameter |
Type |
Description |
linkId |
integer |
Referral link ID |
ruleId |
integer |
Commission rule ID |
Request Body
All fields optional.
| Field |
Type |
Constraints |
Description |
commission_rate |
float |
0–100 |
Updated commission percentage |
label |
string|null |
max 255 |
Updated label. Send null to clear |
priority |
integer |
min 0 |
Updated priority |
valid_from |
date|null |
— |
Updated start date. Send null to remove |
valid_until |
date|null |
≥ valid_from if both present |
Updated expiry. Send null to remove |
max_conversions |
integer|null |
min 1 |
Updated cap. Send null to remove cap |
is_active |
boolean |
— |
Enable or disable the rule |
Example Request — Disable a rule
curl -X PATCH "api.heldsway.com/api//v1/links/10/commission-rules/8" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "is_active": false }'
Example Request — Extend validity window
curl -X PATCH "api.heldsway.com/api//v1/links/10/commission-rules/8" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "valid_until": "2026-05-14" }'
Success Response — 200 OK
Returns the updated Commission Rule Object.
Error Responses
| Status |
Code |
Description |
404 |
NOT_FOUND |
Link or rule not found for this business |
422 |
VALIDATION_ERROR |
Invalid field values |
Delete Commission Rule
Permanently delete a commission rule. This cannot be undone. In-progress conversions already attributed to this rule are not affected.
DELETE /v1/links/{linkId}/commission-rules/{ruleId}
- Required scope:
affiliates:write
- Rate limit: 60 requests/minute
Path Parameters
| Parameter |
Type |
Description |
linkId |
integer |
Referral link ID |
ruleId |
integer |
Commission rule ID |
Example Request
curl -X DELETE "api.heldsway.com/api//v1/links/10/commission-rules/8" \
-H "Authorization: Bearer <access_token>"
Success Response — 204 No Content
Empty body.
Error Responses
| Status |
Code |
Description |
404 |
NOT_FOUND |
Link or rule not found for this business |
Rate Limits
| Endpoint Group |
Limit |
GET read endpoints |
120 requests/minute |
POST, PATCH, PUT, DELETE write endpoints |
60 requests/minute |
POST /v1/affiliates/register |
30 requests/minute |
When a rate limit is exceeded, the API returns HTTP 429 Too Many Requests with the following headers:
Retry-After: 30
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
Wait for the number of seconds indicated by Retry-After before retrying.
Error Reference
All errors follow the standard envelope:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description",
"details": { }
}
}
details is only present on VALIDATION_ERROR responses.
Error Codes
| HTTP Status |
Code |
Description |
400 |
BAD_REQUEST |
Generic bad request |
401 |
UNAUTHORIZED |
Missing, invalid, or expired Bearer token |
403 |
FORBIDDEN |
Valid token but insufficient scope, or feature disabled |
403 |
REGISTRATION_DISABLED |
Self-registration is turned off for this business |
404 |
NOT_FOUND |
Resource does not exist or does not belong to this business |
409 |
AFFILIATE_EXISTS |
Duplicate affiliate — email already registered for this business |
409 |
INVALID_STATUS |
Status transition is not valid from the current state |
422 |
VALIDATION_ERROR |
Request body failed validation |
429 |
TOO_MANY_REQUESTS |
Rate limit exceeded |
500 |
SERVER_ERROR |
Internal server error |
Validation Error Example
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": {
"email": ["The email field is required."],
"commission_rate": ["The commission rate must not be greater than 100."]
}
}
}
Quick Reference
Affiliate Endpoints
| Method |
Path |
Scope |
Description |
GET |
/v1/affiliates |
affiliates:read |
List affiliates |
GET |
/v1/affiliates/{id} |
affiliates:read |
Get affiliate |
POST |
/v1/affiliates |
affiliates:write |
Create affiliate (active) |
POST |
/v1/affiliates/register |
affiliates:write |
Affiliate self-registration (pending) |
PATCH |
/v1/affiliates/{id} |
affiliates:write |
Update affiliate |
DELETE |
/v1/affiliates/{id} |
affiliates:write |
Delete affiliate |
POST |
/v1/affiliates/{id}/approve |
affiliates:write |
Approve pending affiliate |
POST |
/v1/affiliates/{id}/suspend |
affiliates:write |
Suspend affiliate |
POST |
/v1/affiliates/{id}/reactivate |
affiliates:write |
Reactivate suspended affiliate |
POST |
/v1/affiliates/{id}/terminate |
affiliates:write |
Terminate affiliate (permanent) |
Referral Link Endpoints
| Method |
Path |
Scope |
Description |
GET |
/v1/links |
affiliates:read |
List all links |
GET |
/v1/affiliates/{id}/links |
affiliates:read |
List links for one affiliate |
POST |
/v1/affiliates/{id}/links |
affiliates:write |
Create referral link |
PATCH |
/v1/links/{id} |
affiliates:write |
Update referral link |
DELETE |
/v1/links/{id} |
affiliates:write |
Delete referral link |
Commission Endpoints
| Method |
Path |
Scope |
Description |
GET |
/v1/affiliates/{id}/commission |
affiliates:read |
Get affiliate commission config |
PUT |
/v1/affiliates/{id}/commission |
affiliates:write |
Set/clear affiliate commission override |
GET |
/v1/links/{id}/commission-rules |
affiliates:read |
List commission rules for link |
POST |
/v1/links/{id}/commission-rules |
affiliates:write |
Create commission rule |
PATCH |
/v1/links/{linkId}/commission-rules/{ruleId} |
affiliates:write |
Update commission rule |
DELETE |
/v1/links/{linkId}/commission-rules/{ruleId} |
affiliates:write |
Delete commission rule |