Appearance
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
bash
curl "https://heldsway.com/api/v1/affiliates/42/commission" \
-H "Authorization: Bearer <access_token>"Success Response — 200 OK
json
{
"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
bash
curl -X PUT "https://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
bash
curl -X PUT "https://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
json
{
"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
bash
curl "https://heldsway.com/api/v1/links/10/commission-rules" \
-H "Authorization: Bearer <access_token>"Success Response — 200 OK
json
{
"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 |
Example Request — Timed promotional rule
bash
curl -X POST "https://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
bash
curl -X POST "https://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
json
{
"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_countis 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
bash
curl -X PATCH "https://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
bash
curl -X PATCH "https://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
bash
curl -X DELETE "https://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:
text
Retry-After: 30
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0Wait for the number of seconds indicated by Retry-After before retrying.
Error Reference
All errors follow the standard envelope:
json
{
"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
json
{
"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 |