Appearance
Orders & Commissions API
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.md.
| 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 | Start of date range (inclusive) |
to | date | No | — | YYYY-MM-DD, must be >= from | End of date range (inclusive) |
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
bash
curl "https://heldsway.com/api/v1/orders?status=pending&sort=order_total&direction=desc&per_page=10" \
-H "Authorization: Bearer <access_token>"Success Response — HTTP 200
json
{
"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",
"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 |
Get Order Stats — GET /v1/orders/stats
Returns aggregated summary statistics for all conversions. Optionally filter by date range.
Query Parameters
| Parameter | Type | Required | Constraints | Description |
|---|---|---|---|---|
from | date | No | YYYY-MM-DD | Start of date range |
to | date | No | YYYY-MM-DD, must be >= from | End of date range |
Example
bash
curl "https://heldsway.com/api/v1/orders/stats?from=2026-04-01&to=2026-04-15" \
-H "Authorization: Bearer <access_token>"Success Response — HTTP 200
json
{
"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 | Total number of conversions |
total_revenue | number | Sum of order_total across all conversions |
total_commission | number | Sum of commission_amount across all conversions |
pending_commission | number | Sum of commission_amount for pending conversions |
approved_commission | number | Sum of commission_amount for approved conversions |
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
bash
curl "https://heldsway.com/api/v1/orders/42" \
-H "Authorization: Bearer <access_token>"Success Response — HTTP 200
json
{
"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
json
{
"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
bash
curl -X POST "https://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
json
{
"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)
json
{
"success": false,
"error": {
"code": "INVALID_STATUS",
"message": "Only pending conversions can be approved. Current status: approved"
}
}Error — HTTP 404
json
{
"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
bash
curl -X POST "https://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
json
{
"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)
json
{
"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
bash
curl -X POST "https://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
json
{
"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
json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": {
"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
bash
curl -X POST "https://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
json
{
"success": true,
"message": "2 order(s) rejected.",
"data": {
"rejected_count": 2,
"requested_count": 2,
"skipped_count": 0
}
}Export Orders — GET /v1/orders/export
Returns a CSV file containing conversions matching the provided filters.
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 conversion status |
affiliate_id | integer | No | Valid affiliate ID | Filter by affiliate |
from | date | No | YYYY-MM-DD | Start of date range (inclusive) |
to | date | No | YYYY-MM-DD | End of date range (inclusive) |
Example
bash
curl "https://heldsway.com/api/v1/orders/export?status=approved&from=2026-04-01&to=2026-04-30" \
-H "Authorization: Bearer <access_token>" \
-o "approved_orders_april.csv"Success Response — HTTP 200
Content-Type: text/csvContent-Disposition: attachment; filename="conversions_export_2026-04-15_103000.csv"
CSV Columns
| Column | Description |
|---|---|
ID | Internal conversion ID |
Order ID | External order identifier |
Affiliate Name | Name of the attributed affiliate |
Referral Code | Affiliate's referral code |
Customer Name | Customer name (if available) |
Customer Email | Customer email (if available) |
Subtotal | Pre-discount amount |
Discount | Discount applied |
Order Total | Gross total |
Commission Rate | Commission percentage applied |
Commission Amount | Computed commission |
Currency | Order currency code |
Status | pending, approved, rejected, or cancelled |
Converted At | UTC timestamp of conversion |
Conversion Status Workflow
- Pending: Initial state when a conversion is tracked.
- Approved: Explicitly approved by the merchant. Commission is owed.
- Rejected: Explicitly rejected by the merchant (e.g., fraud, return). Commission is voided.
- Cancelled: Order cancelled via ecommerce integration webhook. Commission is voided.
Valid Transitions:
pending➔approvedpending➔rejectedpending➔cancelled
Once approved, rejected, or cancelled, the status is terminal and cannot be changed via the API.
Error Reference
| HTTP Status | Code | Description |
|---|---|---|
401 | UNAUTHORIZED | Missing, invalid, or expired Bearer token |
403 | FORBIDDEN | Missing required orders:read or orders:write scope |
404 | NOT_FOUND | Order not found or doesn't belong to this business |
409 | INVALID_STATUS | Attempted invalid status transition |
422 | VALIDATION_ERROR | Request parameters failed validation |
Rate Limiting
| Action | Limit |
|---|---|
| Read (List, Stats, Detail) | 120 requests/minute |
| Write (Approve, Reject, Bulk) | 60 requests/minute |
| Export | 30 requests/minute |