HeldSway

Business Settings API

Note: Every endpoint in this document requires an active subscription. Without one it returns 402 SUBSCRIPTION_REQUIRED; see the REST API Overview.

Configure your affiliate program settings, branding, commission tiers, and payout schedules programmatically. These endpoints mirror the settings available in the business admin panel at /settings.


Authentication

Requires a Bearer access token with the appropriate scope:

Scope Grants Access To
settings:read Retrieve settings, branding, commission tiers, and payout settings
settings:write Update settings, branding, manage commission tiers, and update payout settings
Authorization: Bearer <access_token>

Base URL: https://api.heldsway.com/api. Endpoint paths in this document (/v1/...) are relative to it, so GET /v1/settings is https://api.heldsway.com/api/v1/settings. Endpoint paths in this document (/v1/...) are relative to https://api.heldsway.com/api.


Rate Limits

Scope Limit
settings:read 120 requests/minute
settings:write 60 requests/minute


Data Models

Settings Object

The full settings object returned by GET /v1/settings and PUT /v1/settings:

{
  "commission_rate": 10.0,
  "cookie_duration": 30,
  "auto_approve_enabled": false,
  "auto_approve_delay_days": 0,
  "auto_approve_min_amount": null,
  "auto_approve_max_amount": null,
  "allow_self_registration": false,
  "store_catalog_path": "products-list"
}

Settings Field Reference

Field Type Default Constraints Description
commission_rate float|null null 0 – 100 (percentage) or 0 – 999999.99 (fixed) Default commission rate for all affiliates. null uses the platform default rate. Per-affiliate overrides take priority.
cookie_duration integer 30 1 – 365 How long the affiliate tracking cookie lasts in days. Conversions within this window are attributed to the referring affiliate.
auto_approve_enabled boolean false — When enabled, pending conversions matching the criteria below are automatically approved.
auto_approve_delay_days integer 0 0 – 365 Number of days to wait after a conversion before auto-approving. Allows a refund window.
auto_approve_min_amount float|null null ≥ 0 Only auto-approve conversions with order amount above this value. null = no minimum.
auto_approve_max_amount float|null null ≥ 0 Only auto-approve conversions with order amount below this value. null = no maximum.
allow_self_registration boolean false — When enabled, anyone can sign up as an affiliate at /affiliate/join. New affiliates will have a “pending” status until approved.
store_catalog_path string "products-list" max 64, alphanumeric, -, _, / Relative URL path to the storefront product catalog for auto-generated store referral links.

Branding Object

{
  "logo_url": "https://s3.amazonaws.com/your-bucket/logo.png",
  "primary_color": "#FF6B2B"
}
Field Type Description
logo_url string|null Resolved URL for the business logo. Returns the external URL if set via API, or the local storage URL if uploaded via the admin panel. null if no logo is configured.
primary_color string|null Brand color in hex format (#RRGGBB). null if not configured.

Commission Tier Object

{
  "id": 12,
  "sort_order": 0,
  "type": "percentage",
  "min_amount": "0.00",
  "max_amount": "500.00",
  "rate": "8.00"
}
Field Type Description
id integer Unique tier identifier (only present on business tiers, not platform tiers)
sort_order integer Display order (only present on business tiers)
type string Calculation mode: "percentage" or "fixed"
min_amount string Minimum order amount for this tier (decimal string)
max_amount string|null Maximum order amount. null means unlimited (no upper bound).
rate string Commission rate percentage or fixed amount for this tier (decimal string)

Commission Priority

When resolving the effective commission rate for a conversion, the system evaluates in this order (highest priority wins):

Per-affiliate rate  >  Business flat rate  >  Business tiers  >  Platform tiers  >  Platform base rate

Payout Settings Object

The payout configuration returned by GET /v1/settings/payouts and PUT /v1/settings/payouts:

{
  "payout_frequency": "monthly",
  "payout_day": 1,
  "min_payout": "50.00",
  "currency": "USD",
  "allow_early_requests": true,
  "auto_create_payouts": true,
  "next_payout_date": "2026-11-01"
}
Field Type Description
payout_frequency string Payout schedule: "weekly" or "monthly"
payout_day integer Scheduled day: 1–7 (Monday=1, Sunday=7) for weekly, or 1–31 for monthly
min_payout string Minimum accrued balance required before an automatic payout is triggered
currency string Business currency code (e.g. "USD")
allow_early_requests boolean Whether affiliates may request an early payout before the scheduled date
auto_create_payouts boolean When true, pending payout records are automatically generated on payout days
next_payout_date string|null Estimated date of the next payout cycle (YYYY-MM-DD), or null if disabled

General Settings

Get All Settings

Retrieve all affiliate program settings for the business.

GET /v1/settings

Scope: settings:read
Rate limit: 120 requests/minute

Example request:

curl "https://api.heldsway.com/api/v1/settings"   -H "Authorization: Bearer <token>"

Response — 200 OK

{
  "success": true,
  "message": "OK",
  "data": {
    "commission_rate": null,
    "cookie_duration": 30,
    "auto_approve_enabled": false,
    "auto_approve_delay_days": 0,
    "auto_approve_min_amount": null,
    "auto_approve_max_amount": null,
    "allow_self_registration": false,
    "store_catalog_path": "products-list"
  }
}

Get Single Setting

Retrieve a single setting by its key.

GET /v1/settings/{key}

Scope: settings:read
Rate limit: 120 requests/minute

Path Parameters

Parameter Type Required Description
key string Yes One of the setting keys from the field reference

Example request:

curl "https://api.heldsway.com/api/v1/settings/cookie_duration"   -H "Authorization: Bearer <token>"

Response — 200 OK

{
  "success": true,
  "message": "OK",
  "data": {
    "key": "cookie_duration",
    "value": 30
  }
}

Error — 404 Not Found (unknown key)

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Unknown setting key."
  }
}

Update Settings (Bulk)

Update one or more settings in a single request. Only fields present in the request body are updated; omitted fields remain unchanged.

PUT /v1/settings
Content-Type: application/json

Scope: settings:write
Rate limit: 60 requests/minute

Body Parameters — All fields are optional. Include only the settings you want to change.

Field Type Constraints Description
commission_type string|null percentage | fixed Commission calculation mode. Defaults to percentage.
commission_rate float|null ≥ 0 (max 100 for percentage, max 999999.99 for fixed) Default commission rate or fixed amount
cookie_duration integer|null 1 – 365 Cookie duration in days
auto_approve_enabled boolean|null — Enable auto-approval
auto_approve_delay_days integer|null 0 – 365 Delay before auto-approving
auto_approve_min_amount float|null ≥ 0 Minimum amount for auto-approval
auto_approve_max_amount float|null ≥ 0 Maximum amount for auto-approval
allow_self_registration boolean|null — Allow public affiliate signup
store_catalog_path string|null max 64, regex /^[a-zA-Z0-9_\-\/]+$/ Store catalog path for generated links

Example request:

curl -X PUT "https://api.heldsway.com/api/v1/settings"   -H "Authorization: Bearer <token>"   -H "Content-Type: application/json"   -d '{
    "commission_rate": 12.5,
    "cookie_duration": 45,
    "auto_approve_enabled": true,
    "auto_approve_delay_days": 7,
    "store_catalog_path": "catalog"
  }'

Response — 200 OK — Returns the full settings object after the update.

{
  "success": true,
  "message": "Settings updated.",
  "data": {
    "commission_rate": 12.5,
    "cookie_duration": 45,
    "auto_approve_enabled": true,
    "auto_approve_delay_days": 7,
    "auto_approve_min_amount": null,
    "auto_approve_max_amount": null,
    "allow_self_registration": false,
    "store_catalog_path": "catalog"
  }
}

Error — 422 Unprocessable Entity (validation failure — Laravel’s standard validation body from UpdateBusinessSettingsApiRequest)

{
  "message": "The commission rate field must not be greater than 100.",
  "errors": {
    "commission_rate": ["The commission rate field must not be greater than 100."]
  }
}

Update Single Setting

Update a single setting by its key.

PUT /v1/settings/{key}
Content-Type: application/json

Scope: settings:write
Rate limit: 60 requests/minute

Path Parameters

Parameter Type Required Description
key string Yes One of the setting keys from the field reference

Body Parameters

Field Type Required Description
value mixed Yes The new value. Type and constraints depend on the key (see field reference).

Example request:

curl -X PUT "https://api.heldsway.com/api/v1/settings/cookie_duration"   -H "Authorization: Bearer <token>"   -H "Content-Type: application/json"   -d '{ "value": 90 }'

Response — 200 OK

{
  "success": true,
  "message": "Setting updated.",
  "data": {
    "key": "cookie_duration",
    "value": 90
  }
}

Error — 403 Forbidden (unknown or disallowed key — UpdateSingleSettingApiRequest::authorize() returns false, so Laravel’s authorization response is returned, with no envelope or code)

{
  "message": "This action is unauthorized."
}

Error — 422 Unprocessable Entity (invalid value for the key — Laravel’s standard validation body from UpdateSingleSettingApiRequest)

{
  "message": "The value field must be at least 1.",
  "errors": {
    "value": ["The value field must be at least 1."]
  }
}

Branding

Get Branding

Retrieve the business branding configuration (logo and primary color).

GET /v1/settings/branding

Scope: settings:read
Rate limit: 120 requests/minute

Example request:

curl "https://api.heldsway.com/api/v1/settings/branding"   -H "Authorization: Bearer <token>"

Response — 200 OK

{
  "success": true,
  "message": "OK",
  "data": {
    "logo_url": "https://s3.amazonaws.com/your-bucket/logo.png",
    "primary_color": "#FF6B2B"
  }
}

If no branding is configured:

{
  "success": true,
  "message": "OK",
  "data": {
    "logo_url": null,
    "primary_color": null
  }
}

Update Branding

Update the business logo URL and/or primary brand color. You can also remove the logo by sending remove_logo: true.

PUT /v1/settings/branding
Content-Type: application/json

Scope: settings:write
Rate limit: 60 requests/minute

Body Parameters — All fields are optional. Include only what you want to change.

Field Type Constraints Description
logo_url string|null Valid URL, max 2048 chars External URL for the business logo (e.g. S3, CDN, or any public URL). Pass null or omit to leave unchanged.
primary_color string|null Hex format #RRGGBB Brand color used in affiliate-facing pages. Pass null or omit to leave unchanged.
remove_logo boolean — Set to true to remove the current logo entirely (clears both external URL and any uploaded file).

Example — Set logo and color:

curl -X PUT "https://api.heldsway.com/api/v1/settings/branding"   -H "Authorization: Bearer <token>"   -H "Content-Type: application/json"   -d '{
    "logo_url": "https://cdn.example.com/logos/acme.png",
    "primary_color": "#1A2B3C"
  }'

Response — 200 OK

{
  "success": true,
  "message": "Branding updated.",
  "data": {
    "logo_url": "https://cdn.example.com/logos/acme.png",
    "primary_color": "#1A2B3C"
  }
}

Example — Remove logo:

curl -X PUT "https://api.heldsway.com/api/v1/settings/branding"   -H "Authorization: Bearer <token>"   -H "Content-Type: application/json"   -d '{ "remove_logo": true }'

Response — 200 OK

{
  "success": true,
  "message": "Branding updated.",
  "data": {
    "logo_url": null,
    "primary_color": "#1A2B3C"
  }
}

Error — 422 Unprocessable Entity (Laravel’s standard validation body from UpdateBrandingApiRequest)

{
  "message": "The logo url field must be a valid URL. (and 1 more error)",
  "errors": {
    "logo_url": ["The logo url field must be a valid URL."],
    "primary_color": ["The primary color field format is invalid."]
  }
}

Commission Tiers

Commission tiers allow you to configure variable commission rates based on order amount. Each tier defines a min/max range and the commission rate applied when an order falls within that range.

Businesses can define custom tiers that override the platform default tiers. When no custom tiers exist, the platform defaults are used.

Get Commission Tiers

Retrieve both platform default tiers and custom business tiers.

GET /v1/settings/commission-tiers

Scope: settings:read
Rate limit: 120 requests/minute

Example request:

curl "https://api.heldsway.com/api/v1/settings/commission-tiers"   -H "Authorization: Bearer <token>"

Response — 200 OK (business has custom tiers)

{
  "success": true,
  "message": "OK",
  "data": {
    "using_custom": true,
    "platform_tiers": [
      { "type": "percentage", "min_amount": "0.00", "max_amount": "100.00", "rate": "5.00" },
      { "type": "percentage", "min_amount": "100.00", "max_amount": null, "rate": "10.00" }
    ],
    "business_tiers": [
      { "id": 12, "sort_order": 0, "type": "percentage", "min_amount": "0.00", "max_amount": "500.00", "rate": "8.00" },
      { "id": 13, "sort_order": 1, "type": "percentage", "min_amount": "500.00", "max_amount": null, "rate": "12.00" }
    ]
  }
}

Response — 200 OK (no custom tiers, using platform defaults)

{
  "success": true,
  "message": "OK",
  "data": {
    "using_custom": false,
    "platform_tiers": [
      { "type": "percentage", "min_amount": "0.00", "max_amount": "100.00", "rate": "5.00" },
      { "type": "percentage", "min_amount": "100.00", "max_amount": null, "rate": "10.00" }
    ],
    "business_tiers": []
  }
}

Response Fields

Field Type Description
using_custom boolean true if the business has custom tiers defined; false if using platform defaults
platform_tiers array Read-only platform default tiers. Always returned for reference.
business_tiers array Custom tiers defined by the business. Empty array if none exist.

Create Commission Tier

Add a new custom commission tier. The tier range must not overlap with existing business tiers.

POST /v1/settings/commission-tiers
Content-Type: application/json

Scope: settings:write
Rate limit: 60 requests/minute

Body Parameters

Field Type Required Constraints Description
min_amount numeric Yes ≥ 0 Minimum order amount for this tier
max_amount numeric|null No ≥ 0, must be > min_amount Maximum order amount. Omit or pass null for unlimited (no upper bound).
commission_type string No percentage | fixed Commission calculation mode. Defaults to percentage.
rate numeric Yes ≥ 0 (max 100 for percentage, max 999999.99 for fixed) Commission rate percentage or fixed amount

Example request:

curl -X POST "https://api.heldsway.com/api/v1/settings/commission-tiers"   -H "Authorization: Bearer <token>"   -H "Content-Type: application/json"   -d '{
    "min_amount": 0,
    "max_amount": 500,
    "commission_type": "percentage",
    "rate": 8
  }'

Response — 201 Created

{
  "success": true,
  "message": "Created",
  "data": {
    "id": 12,
    "sort_order": 0,
    "type": "percentage",
    "min_amount": "0.00",
    "max_amount": "500.00",
    "rate": "8.00"
  }
}

Error — 422 Unprocessable Entity (overlapping range)

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "min_amount": ["This tier range overlaps with an existing tier."]
    }
  }
}

Error — 422 Unprocessable Entity (min >= max)

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "min_amount": ["Minimum amount must be less than maximum amount."]
    }
  }
}

Update Commission Tier

Update an existing business commission tier. The updated range must not overlap with other tiers.

PUT /v1/settings/commission-tiers/{id}
Content-Type: application/json

Scope: settings:write
Rate limit: 60 requests/minute

Path Parameters

Parameter Type Required Description
id integer Yes The tier ID (from the id field in business tier objects)

Body Parameters — Same as Create Commission Tier.

Example request:

curl -X PUT "https://api.heldsway.com/api/v1/settings/commission-tiers/12"   -H "Authorization: Bearer <token>"   -H "Content-Type: application/json"   -d '{
    "min_amount": 0,
    "max_amount": 750,
    "commission_type": "percentage",
    "rate": 10
  }'

Response — 200 OK

{
  "success": true,
  "message": "Commission tier updated.",
  "data": {
    "id": 12,
    "sort_order": 0,
    "type": "percentage",
    "min_amount": "0.00",
    "max_amount": "750.00",
    "rate": "10.00"
  }
}

Error — 404 Not Found

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Commission tier not found."
  }
}

Note: Tiers are scoped to the business associated with your API key. You cannot access or modify tiers belonging to another business.


Delete Commission Tier

Delete a single business commission tier.

DELETE /v1/settings/commission-tiers/{id}

Scope: settings:write
Rate limit: 60 requests/minute

Path Parameters

Parameter Type Required Description
id integer Yes The tier ID to delete

Example request:

curl -X DELETE "https://api.heldsway.com/api/v1/settings/commission-tiers/12"   -H "Authorization: Bearer <token>"

Response — 204 No Content

No response body.

Error — 404 Not Found

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Commission tier not found."
  }
}

Reset Commission Tiers

Delete all custom business tiers, reverting the business to use platform default tiers.

POST /v1/settings/commission-tiers/reset

Scope: settings:write
Rate limit: 60 requests/minute

Example request:

curl -X POST "https://api.heldsway.com/api/v1/settings/commission-tiers/reset"   -H "Authorization: Bearer <token>"

Response — 200 OK

{
  "success": true,
  "message": "Commission tiers reset to platform defaults."
}

Payout Settings

Configure the schedule, minimum accrued threshold, and rules for generating affiliate payouts.

Get Payout Settings

Retrieve current payout configuration and the estimated date of the next payout cycle.

GET /v1/settings/payouts

Scope: settings:read
Rate limit: 120 requests/minute

Example request:

curl "https://api.heldsway.com/api/v1/settings/payouts"   -H "Authorization: Bearer <token>"

Response — 200 OK

{
  "success": true,
  "message": "OK",
  "data": {
    "payout_frequency": "monthly",
    "payout_day": 1,
    "min_payout": "50.00",
    "currency": "USD",
    "allow_early_requests": true,
    "auto_create_payouts": true,
    "next_payout_date": "2026-11-01"
  }
}

Update Payout Settings

Update payout frequency, scheduling, minimum payout threshold, and early request options.

PUT /v1/settings/payouts
Content-Type: application/json

Scope: settings:write
Rate limit: 60 requests/minute

Body Parameters

Field Type Required Constraints Description
payout_frequency string Yes weekly, monthly How often payouts are generated
payout_day integer Yes 1–7 (if weekly), 1–31 (if monthly) Scheduled payout day of week or month
min_payout numeric Yes ≥ 0 Minimum earnings required before an automatic payout is created
allow_early_requests boolean Yes — Whether affiliates may request an early payout before the scheduled date
auto_create_payouts boolean Yes — Automatically generate pending payout records on scheduled payout days

Example request:

curl -X PUT "https://api.heldsway.com/api/v1/settings/payouts" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "payout_frequency": "monthly",
    "payout_day": 15,
    "min_payout": 100.00,
    "allow_early_requests": false,
    "auto_create_payouts": true
  }'

Response — 200 OK

{
  "success": true,
  "message": "Payout settings updated.",
  "data": {
    "payout_frequency": "monthly",
    "payout_day": 15,
    "min_payout": "100.00",
    "currency": "USD",
    "allow_early_requests": false,
    "auto_create_payouts": true,
    "next_payout_date": "2026-11-15"
  }
}

Error — 422 Unprocessable Entity (Laravel’s standard validation body from UpdatePayoutSettingsApiRequest)

{
  "message": "The payout day field must not be greater than 7.",
  "errors": {
    "payout_day": ["The payout day field must not be greater than 7."]
  }
}

Error Reference

All endpoints follow the standard response envelope.

HTTP Status Error Code Cause
401 UNAUTHORIZED Missing or invalid Bearer token
402 SUBSCRIPTION_REQUIRED The business has no active subscription (see the callout at the top of this document)
403 FORBIDDEN Token does not have the required scope (settings:read or settings:write)
403 — PUT /v1/settings/{key} with a key outside the allowed list; Laravel’s authorization body {"message": "This action is unauthorized."}
403 FEATURE_NOT_AVAILABLE The plan does not include the feature: PUT /v1/settings/branding needs custom-branded-portal-your-domain-logo; creating, updating, deleting or resetting commission tiers needs 2-level-multi-tier-performance-tiers
404 NOT_FOUND Unknown setting key, or tier not found / belongs to another business
422 VALIDATION_ERROR Commission-tier range conflict found after the request passed validation (overlapping range, or min ≥ max); per-field messages in details
422 — Invalid request body rejected by the endpoint’s Form Request. The body is Laravel’s standard validation response (message + errors) with no code
429 RATE_LIMIT_EXCEEDED Rate limit exceeded
500 SERVER_ERROR Unexpected server error

Quick Reference

Method Path Scope Throttle Description
GET /v1/settings settings:read 120/min Get all affiliate program settings
GET /v1/settings/{key} settings:read 120/min Get a single setting by key
PUT /v1/settings settings:write 60/min Bulk update settings
PUT /v1/settings/{key} settings:write 60/min Update a single setting
GET /v1/settings/branding settings:read 120/min Get branding configuration
PUT /v1/settings/branding settings:write 60/min Update branding (logo URL, color)
GET /v1/settings/commission-tiers settings:read 120/min Get platform and business tiers
POST /v1/settings/commission-tiers settings:write 60/min Create a business tier
PUT /v1/settings/commission-tiers/{id} settings:write 60/min Update a business tier
DELETE /v1/settings/commission-tiers/{id} settings:write 60/min Delete a business tier
POST /v1/settings/commission-tiers/reset settings:write 60/min Reset to platform defaults
GET /v1/settings/payouts settings:read 120/min Get payout settings & next payout date
PUT /v1/settings/payouts settings:write 60/min Update payout settings