Orders & Commissions API
Manage tracked conversions, line-item order details, commission review, approvals, bulk moderation, and CSV exports across all store locations.
Manage tracked conversions (orders), view commission statistics, approve or reject pending commissions, and export data.
Authentication
All endpoints require a Bearer access token with the appropriate scope. See Authentication.
| Scope |
Access |
orders:read |
List, show, stats, export |
orders:write |
Approve, reject, bulk approve, bulk reject |
Endpoints
| Method |
Path |
Scope |
Throttle |
Description |
GET |
/v1/orders |
orders:read |
120/min |
List orders (paginated) |
GET |
/v1/orders/stats |
orders:read |
120/min |
Aggregated statistics |
GET |
/v1/orders/export |
orders:read |
30/min |
CSV export |
GET |
/v1/orders/{id} |
orders:read |
120/min |
Single order detail |
POST |
/v1/orders/{id}/approve |
orders:write |
60/min |
Approve pending order |
POST |
/v1/orders/{id}/reject |
orders:write |
60/min |
Reject pending order |
POST |
/v1/orders/bulk-approve |
orders:write |
60/min |
Bulk approve |
POST |
/v1/orders/bulk-reject |
orders:write |
60/min |
Bulk reject |
List Orders — GET /v1/orders
Returns a paginated list of conversions with filtering, sorting, and search.
Query Parameters
| Parameter |
Type |
Required |
Default |
Constraints |
Description |
search |
string |
No |
— |
max:255 |
Search by order ID or affiliate name |
status |
string |
No |
— |
pending, approved, rejected, cancelled |
Filter by conversion status |
affiliate_id |
integer |
No |
— |
Valid affiliate ID for this business |
Filter by affiliate |
from |
date |
No |
— |
YYYY-MM-DD or ISO 8601 date-time |
Start of date range (inclusive). A bare date starts at 00:00:00 UTC; a date-time is used as an exact instant |
to |
date |
No |
— |
YYYY-MM-DD or ISO 8601 date-time, must be >= from |
End of date range (inclusive). A bare date ends at 23:59:59 UTC; a date-time is used as an exact instant |
attribution |
string |
No |
all |
all, attributed, unattributed |
Filter by attribution state |
location_id |
string |
No |
— |
max:64 |
Filter by store location ID |
source_domain |
string |
No |
— |
max:255 |
Filter by origin storefront domain |
sort |
string |
No |
converted_at |
order_id, order_total, commission_amount, converted_at, status |
Sort field |
direction |
string |
No |
desc |
asc, desc |
Sort direction |
per_page |
integer |
No |
25 |
1–100 |
Items per page |
page |
integer |
No |
1 |
min:1 |
Page number |
Example
curl "https://api.heldsway.com/api/v1/orders?status=pending&sort=order_total&direction=desc&per_page=10" \
-H "Authorization: Bearer <access_token>"
Success Response — HTTP 200
{
"success": true,
"message": "OK",
"data": {
"items": [
{
"id": 42,
"order_id": "#135419",
"affiliate": {
"id": 7,
"name": "Salman",
"referral_code": "SALMAN2026"
},
"customer": {
"name": "Geonwoo Park",
"email": "geonwoo@example.com"
},
"subtotal": "70.00",
"discount_applied": "0.00",
"tax": "0.00",
"order_total": "70.00",
"commission_rate": "10.00",
"commission_amount": "7.00",
"currency": "USD",
"location_id": "STORE-42",
"location_name": "Downtown Store",
"source_domain": "rentmy.com",
"status": "pending",
"converted_at": "2026-04-10T14:30:00.000000Z",
"created_at": "2026-04-10T14:30:00.000000Z"
},
{
"id": 41,
"order_id": "#135380",
"affiliate": null,
"customer": null,
"subtotal": "140.00",
"discount_applied": "0.00",
"tax": "0.00",
"order_total": "140.00",
"commission_rate": "0.00",
"commission_amount": "0.00",
"currency": "USD",
"status": "approved",
"converted_at": "2026-04-08T14:30:00.000000Z",
"created_at": "2026-04-08T14:30:00.000000Z"
}
],
"meta": {
"current_page": 1,
"per_page": 10,
"total": 2,
"last_page": 1
}
}
}
Response Fields
| Field |
Type |
Description |
items[].id |
integer |
Internal conversion record ID |
items[].order_id |
string |
External order identifier |
items[].affiliate |
object|null |
Attributed affiliate (null if unattributed) |
items[].affiliate.id |
integer |
Affiliate ID |
items[].affiliate.name |
string |
Affiliate’s display name |
items[].affiliate.referral_code |
string |
Affiliate’s referral code |
items[].customer |
object|null |
Customer info (null if no customer data) |
items[].customer.name |
string|null |
Customer name |
items[].customer.email |
string|null |
Customer email |
items[].subtotal |
string |
Pre-discount amount (2 decimal places) |
items[].discount_applied |
string |
Discount amount |
items[].tax |
string |
Tax amount |
items[].order_total |
string |
Gross total |
items[].commission_rate |
string |
Commission rate (%) applied |
items[].commission_amount |
string |
Computed commission amount |
items[].currency |
string |
3-letter currency code (default USD) |
items[].status |
string |
pending, approved, rejected, or cancelled |
items[].converted_at |
string|null |
ISO 8601 timestamp of conversion |
items[].created_at |
string |
ISO 8601 timestamp of record creation |
meta.current_page |
integer |
Current page number |
meta.per_page |
integer |
Items per page |
meta.total |
integer |
Total matching records |
meta.last_page |
integer |
Last available page |
Returns aggregated summary statistics for the business’s affiliate-attributed orders. An order counts unless its status is cancelled — pending, approved, rejected and $0 orders all count. Optionally filter by date range. These are the same figures as the stat cards on the business panel’s Orders & Commissions page.
Query Parameters
| Parameter |
Type |
Required |
Constraints |
Description |
from |
date |
No |
YYYY-MM-DD or ISO 8601 date-time |
Start of date range; a bare date starts at 00:00:00 UTC |
to |
date |
No |
YYYY-MM-DD or ISO 8601 date-time, must be >= from |
End of date range; a bare date ends at 23:59:59 UTC |
Example
curl "https://api.heldsway.com/api/v1/orders/stats?from=2026-04-01&to=2026-04-15" \
-H "Authorization: Bearer <access_token>"
Success Response — HTTP 200
{
"success": true,
"message": "OK",
"data": {
"total_orders": 2,
"total_revenue": 210.00,
"total_commission": 14.00,
"pending_commission": 0.00,
"approved_commission": 14.00
}
}
Response Fields
| Field |
Type |
Description |
total_orders |
integer |
Number of counted orders: attributed to an affiliate and not cancelled |
total_revenue |
number |
Sum of each counted order’s revenue: subtotal (or order_total when subtotal is 0 or empty) minus discount_applied, never below 0 per order. Tax and shipping are excluded |
total_commission |
number |
Sum of commission_amount across the counted orders |
pending_commission |
number |
Sum of commission_amount for pending orders |
approved_commission |
number |
Sum of commission_amount for approved orders |
Get Order Detail — GET /v1/orders/{id}
Returns the full detail for a single conversion, including line items and click attribution.
Path Parameters
| Parameter |
Type |
Description |
id |
integer |
Conversion record ID |
Example
curl "https://api.heldsway.com/api/v1/orders/42" \
-H "Authorization: Bearer <access_token>"
Success Response — HTTP 200
{
"success": true,
"message": "OK",
"data": {
"id": 42,
"order_id": "#135380",
"affiliate": {
"id": 7,
"name": "Salman",
"referral_code": "SALMAN2026",
"commission_rate": "10.00"
},
"customer": {
"name": "Jane Smith",
"email": "jane@example.com"
},
"subtotal": "140.00",
"discount_applied": "0.00",
"tax": "0.00",
"order_total": "140.00",
"commission_rate": "10.00",
"commission_amount": "14.00",
"currency": "USD",
"status": "approved",
"line_items": [
{ "name": "Mountain Bike Rental", "quantity": 1, "price": "140.00" }
],
"ip_address": "192.168.1.100",
"click": {
"id": 123,
"referral_link_id": 45,
"landing_page": "https://mountainthreads.example.com/bikes",
"referrer": "https://instagram.com",
"created_at": "2026-04-08T10:00:00.000000Z"
},
"converted_at": "2026-04-08T14:30:00.000000Z",
"created_at": "2026-04-08T14:30:00.000000Z",
"updated_at": "2026-04-08T15:00:00.000000Z"
}
}
Additional Detail Fields
These fields appear only in the detail response (not in the list):
| Field |
Type |
Description |
affiliate.commission_rate |
string|null |
Affiliate’s override commission rate (may differ from business default) |
line_items |
array|null |
Product details from the order |
ip_address |
string|null |
Customer’s IP address |
click |
object|null |
Attribution click data (null if direct conversion) |
click.id |
integer |
Click record ID |
click.referral_link_id |
integer |
Associated referral link ID |
click.landing_page |
string|null |
Page URL where the click landed |
click.referrer |
string|null |
Referring URL |
click.created_at |
string |
ISO 8601 timestamp of the click |
updated_at |
string |
ISO 8601 timestamp of last update |
Error — HTTP 404
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Order not found."
}
}
Approve Order — POST /v1/orders/{id}/approve
Transitions a pending conversion to approved status. The commission is considered owed once approved.
Path Parameters
| Parameter |
Type |
Description |
id |
integer |
Conversion record ID |
Body Parameters
| Field |
Type |
Required |
Constraints |
Description |
notes |
string |
No |
max:1000 |
Approval notes (stored in audit log) |
Example
curl -X POST "https://api.heldsway.com/api/v1/orders/42/approve" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "notes": "Verified payment received" }'
Success Response — HTTP 200
{
"success": true,
"message": "Order #135419 approved.",
"data": {
"id": 42,
"order_id": "#135419",
"status": "approved",
"commission_amount": "7.00",
"updated_at": "2026-04-15T12:00:00.000000Z"
}
}
Error — HTTP 409 (Invalid Status Transition)
{
"success": false,
"error": {
"code": "INVALID_STATUS",
"message": "Only pending conversions can be approved. Current status: approved"
}
}
Error — HTTP 404
{
"success": false,
"error": {
"code": "NOT_FOUND",
"message": "Order not found."
}
}
Reject Order — POST /v1/orders/{id}/reject
Transitions a pending conversion to rejected status. The commission is voided.
Path Parameters
| Parameter |
Type |
Description |
id |
integer |
Conversion record ID |
Body Parameters
| Field |
Type |
Required |
Constraints |
Description |
reason |
string |
No |
max:1000 |
Rejection reason (stored in audit log) |
Example
curl -X POST "https://api.heldsway.com/api/v1/orders/42/reject" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "reason": "Fraudulent order - chargeback received" }'
Success Response — HTTP 200
{
"success": true,
"message": "Order #135419 rejected.",
"data": {
"id": 42,
"order_id": "#135419",
"status": "rejected",
"commission_amount": "7.00",
"updated_at": "2026-04-15T12:00:00.000000Z"
}
}
Error — HTTP 409 (Invalid Status Transition)
{
"success": false,
"error": {
"code": "INVALID_STATUS",
"message": "Only pending conversions can be rejected. Current status: approved"
}
}
Bulk Approve — POST /v1/orders/bulk-approve
Approves multiple pending conversions in a single request. Non-pending conversions are silently skipped.
Body Parameters
| Field |
Type |
Required |
Constraints |
Description |
ids |
integer[] |
Yes |
min:1, max:100, each distinct |
Conversion IDs to approve |
Example
curl -X POST "https://api.heldsway.com/api/v1/orders/bulk-approve" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "ids": [42, 43, 44, 45, 46] }'
Success Response — HTTP 200
{
"success": true,
"message": "3 order(s) approved.",
"data": {
"approved_count": 3,
"requested_count": 5,
"skipped_count": 2
}
}
Response Fields
| Field |
Type |
Description |
approved_count |
integer |
Number of conversions actually approved |
requested_count |
integer |
Total IDs submitted in the request |
skipped_count |
integer |
IDs that were skipped (non-existent, wrong business, or not pending) |
Error — HTTP 422
BulkOrderActionApiRequest rejects the body before the controller runs, so the response is Laravel’s standard validation body (see Error Reference → Validation Errors (422)):
{
"message": "The ids field is required.",
"errors": {
"ids": ["The ids field is required."]
}
}
Bulk Reject — POST /v1/orders/bulk-reject
Rejects multiple pending conversions in a single request. Non-pending conversions are silently skipped.
Body Parameters
| Field |
Type |
Required |
Constraints |
Description |
ids |
integer[] |
Yes |
min:1, max:100, each distinct |
Conversion IDs to reject |
reason |
string |
No |
max:1000 |
Rejection reason (applied to all, stored in audit log) |
Example
curl -X POST "https://api.heldsway.com/api/v1/orders/bulk-reject" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "ids": [47, 48], "reason": "Duplicate orders from same session" }'
Success Response — HTTP 200
{
"success": true,
"message": "2 order(s) rejected.",
"data": {
"rejected_count": 2,
"requested_count": 2,
"skipped_count": 0
}
}
Response Fields
| Field |
Type |
Description |
rejected_count |
integer |
Number of conversions actually rejected |
requested_count |
integer |
Total IDs submitted in the request |
skipped_count |
integer |
IDs that were skipped |
Export Orders — GET /v1/orders/export
Downloads all matching conversions as a CSV file. Same filters as the list endpoint but without pagination — returns all matching records up to 10,000 rows.
Query Parameters
| Parameter |
Type |
Required |
Constraints |
Description |
search |
string |
No |
max:255 |
Search by order ID or affiliate name |
status |
string |
No |
pending, approved, rejected, cancelled |
Filter by status |
affiliate_id |
integer |
No |
Valid affiliate ID |
Filter by affiliate |
from |
date |
No |
YYYY-MM-DD or ISO 8601 date-time |
Start of date range; a bare date starts at 00:00:00 UTC |
to |
date |
No |
YYYY-MM-DD or ISO 8601 date-time, must be >= from |
End of date range; a bare date ends at 23:59:59 UTC |
Example
curl "https://api.heldsway.com/api/v1/orders/export?status=approved&from=2026-04-01" \
-H "Authorization: Bearer <access_token>" \
-o orders-export.csv
Success Response — HTTP 200
Content-Type: text/csv Content-Disposition: attachment; filename="orders-export-2026-04-15.csv"
Order ID,Affiliate Name,Affiliate Code,Subtotal,Discount,Tax,Order Total,Commission Rate (%),Commission Amount,Currency,Status,Customer Email,Converted At
#135380,Salman,SALMAN2026,140.00,0.00,0.00,140.00,10.00,14.00,USD,approved,jane@example.com,2026-04-08 14:30:00
#135419,,,70.00,0.00,0.00,70.00,0.00,0.00,USD,pending,geonwoo@example.com,2026-04-10 14:30:00
CSV Columns
| Column |
Description |
| Order ID |
External order identifier |
| Affiliate Name |
Affiliate’s display name (empty if unattributed) |
| Affiliate Code |
Affiliate’s referral code (empty if unattributed) |
| Subtotal |
Pre-discount amount |
| Discount |
Discount applied |
| Tax |
Tax amount |
| Order Total |
Gross total |
| Commission Rate (%) |
Rate applied |
| Commission Amount |
Computed commission |
| Currency |
3-letter currency code |
| Status |
Conversion status |
| Customer Email |
Customer’s email (empty if unavailable) |
| Converted At |
Conversion timestamp |
Conversion Status Workflow
┌─────────┐
│ pending │ ← initial state (from SDK tracking)
└────┬─────┘
│
┌────┴────┐
▼ ▼
┌─────────┐ ┌──────────┐
│ approved│ │ rejected │
└─────────┘ └──────────┘
┌───────────┐
│ cancelled │ ← set by system (order cancellation)
└───────────┘
- Only pending conversions can be approved or rejected via the API.
- Attempting to approve/reject a non-pending conversion returns HTTP
409.
- The
cancelled status is set by the system when an order is cancelled — it is not available as an API action.
Error Reference
| HTTP Status |
Error Code |
Cause |
401 |
UNAUTHORIZED |
Missing or invalid Bearer token |
402 |
SUBSCRIPTION_REQUIRED |
The business has no active subscription (see Error Reference → Subscription Required (402)) |
403 |
FORBIDDEN |
Token does not have required scope (orders:read or orders:write) |
403 |
FEATURE_NOT_AVAILABLE |
GET /v1/orders/export only — the plan does not include CSV export |
404 |
NOT_FOUND |
Conversion ID does not exist or belongs to a different business |
409 |
INVALID_STATUS |
Attempted to approve/reject a non-pending conversion |
422 |
— |
Invalid query parameters or request body. Every orders endpoint validates with a Form Request, so the body is Laravel’s standard validation response with no code (see Error Reference → Validation Errors (422)) |
429 |
RATE_LIMIT_EXCEEDED |
Rate limit exceeded |
Rate Limiting
| Endpoint Group |
Limit |
| Read endpoints (list, stats, show) |
120 requests/min |
| Write endpoints (approve, reject, bulk) |
60 requests/min |
| Export |
30 requests/min |
Exceeding the limit returns HTTP 429 Too Many Requests with error code RATE_LIMIT_EXCEEDED.