HeldSway

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

curl "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",
        "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

curl "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 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

curl "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 "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 "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 "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

{
  "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

curl -X POST "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
  }
}

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

curl "api.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/csv Content-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

  1. Pending: Initial state when a conversion is tracked.
  2. Approved: Explicitly approved by the merchant. Commission is owed.
  3. Rejected: Explicitly rejected by the merchant (e.g., fraud, return). Commission is voided.
  4. Cancelled: Order cancelled via ecommerce integration webhook. Commission is voided.

Valid Transitions:

  • pendingapproved
  • pendingrejected
  • pendingcancelled

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