Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.scrip.dev/llms.txt

Use this file to discover all available pages before exploring further.

The Scrip API is a REST API. All requests and responses use JSON. The current version is v1.
https://api.scrip.dev/v1
If you’re new to Scrip, start with the Quickstart to create a program and process your first event, or read Core Concepts for an overview of the data model.

Authentication

Every request requires an API key in the Authorization header:
curl https://api.scrip.dev/v1/programs \
  -H "Authorization: Bearer sk_your_api_key" \
  -H "Content-Type: application/json"
Keys use the sk_ prefix and have full read/write access to all resources in your organization. You can also pass the key via the X-API-Key header. Create and manage keys from the Scrip dashboard. See the Authentication page for details on key management and rate limits.

Conventions

ConventionDetail
Property namessnake_case
IDsUUIDs (550e8400-e29b-41d4-a716-446655440000)
TimestampsRFC 3339 (2024-01-15T10:30:00Z)
AmountsStrings to preserve decimal precision ("100.00")
Content typeapplication/json for all request and response bodies

Idempotency

Events, balance operations (hold, release, forfeit), redemptions, reversals, and transfers accept an idempotency_key field. Use deterministic keys derived from your domain data (order-12345-completed), not random UUIDs. All resource types behave the same way:
  • Same key + same payload: returns the original response without reprocessing. Events return 202, all other operations return 200.
  • Same key + different payload: returns 409 Conflict with code idempotency_conflict.
Keys are scoped to program_id. Payload comparison uses a SHA-256 hash of semantic fields. Cosmetic differences (JSON key order, trailing decimal zeros, whitespace) are normalized before hashing, so they will not trigger a conflict.

Pagination

List endpoints return paginated results using cursor-based pagination:
{
  "data": [
    { "id": "...", "name": "..." }
  ],
  "pagination": {
    "has_more": true,
    "next_cursor": "eyJ..."
  }
}
Pass cursor as a query parameter to fetch the next page. Use limit to control page size (default 50, max 200). Pagination is stable across concurrent modifications. Inserts and deletes between pages do not cause skipped or duplicated results.
Most list endpoints support query parameters for filtering and ordering results. Available parameters vary by endpoint and are documented in each endpoint’s parameter table.

Filtering

Filter by resource status or related IDs:
GET /v1/participants?status=ACTIVE&program_id=550e8400-...
GET /v1/events?status=COMPLETED&from=2025-01-01T00:00:00Z&to=2025-02-01T00:00:00Z
Time-range filters (from, to) accept RFC 3339 timestamps and filter on the resource’s creation time. from is required when to is provided, and from must be before to.

Sorting

Control result ordering with sort_by and sort_dir:
GET /v1/programs?sort_by=name&sort_dir=asc
GET /v1/events?sort_by=event_timestamp&sort_dir=desc
Each endpoint defines its own set of sortable fields (e.g., created_at, name, order). The default sort is typically created_at descending. Rules default to order ascending. Search uses case-insensitive partial matching. The searched field varies by resource:
ResourceSearched fields
Participantsexternal_id
Programs, Rulesname
Assetsname and symbol
GET /v1/participants?search=user_abc
GET /v1/rules?search=welcome

Errors

Error responses include a machine-readable code and a human-readable message:
{
  "code": "not_found",
  "message": "Program not found"
}
Some errors include a details object with field-level validation information:
{
  "code": "validation_error",
  "message": "Invalid request body",
  "details": {
    "name": "is required",
    "key": "must be lowercase alphanumeric with hyphens"
  }
}

Status codes

CodeMeaning
200Success
201Resource created
202Accepted for async processing (events)
204Success, no content
400Bad request or validation error
401Unauthorized
403Forbidden
404Resource not found
409Conflict (state violation, duplicate idempotency key, reversal exceeds remaining)
422Business rule violation (insufficient funds, inactive resource)
429Rate limit exceeded
500Internal server error

Error codes

The code field in error responses is a machine-readable string you can match on programmatically. Common codes by category:

Validation (400)

CodeDescription
validation_errorOne or more fields failed validation. Check details for field-level errors
invalid_requestRequest structure is invalid (e.g., mutually exclusive fields provided)
invalid_amountAmount is malformed, non-positive, or exceeds asset scale
invalid_quantityQuantity must be a positive integer
asset_not_linkedAsset is not linked to the specified program
reward_program_mismatchReward does not belong to the specified program

Authentication & authorization (401 / 403)

CodeDescription
unauthorizedMissing or invalid API key / JWT
forbiddenValid credentials but insufficient permissions for this action

Not found (404)

CodeDescription
not_foundThe requested resource does not exist

Conflict (409)

CodeDescription
participant_inactiveParticipant is SUSPENDED or CLOSED. Financial operations and counter updates are blocked for inactive participants
idempotency_conflictIdempotency key was already used with different parameters
already_reversedRedemption has already been fully reversed
quantity_exceeds_remainingReversal quantity exceeds the remaining reversible units
amount_exceeds_remainingReversal amount exceeds the remaining reversible amount
max_total_exceededReward’s global inventory limit reached
max_per_participant_exceededReward’s per-participant inventory limit reached
program_archivedProgram is archived and cannot be modified
program_suspendedProgram is suspended and cannot process transactions
key_existsA tier key or reward name already exists in this program

Business rules (422)

CodeDescription
insufficient_fundsNot enough balance for the requested operation
asset_archivedAsset is archived and cannot be used in new operations
program_inactiveProgram is not active; events cannot be ingested
participant_not_foundParticipant does not exist and the program is configured to reject unknown participants
recipient_not_foundTarget participant not found or not enrolled in the program

Rate limits

Requests are rate-limited per organization at 10 requests/second with burst to 30. All API keys in the same organization share one rate limit bucket. Every response includes X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers. When exceeded, the API returns 429 with a Retry-After header. See Authentication for the full header reference.

Resources

ResourcePrefixDescription
Programs/v1/programsTop-level containers for incentive logic
Assets/v1/assetsUnits of value (points, credits, cashback)
Participants/v1/participantsUsers who earn and spend
Groups/v1/groupsCollections of participants
Rules/v1/rulesCEL conditions and reward actions
Events/v1/eventsSignals that trigger rule evaluation
Tiers/v1/programs/{id}/tiersStatus hierarchies for participants
Redemptions/v1/participants/{id}/redemptionsBalance spend operations
Rewards/v1/programs/{id}/rewardsCatalog items for redemption
Transfers/v1/transfersValue movement between participants
Automations/v1/programs/{id}/automationsScheduled event generation
Reporting/v1/reportsLedger summaries and activity
Logs/v1/logsRequest history and usage metrics
For a complete map of entities and their relationships, see the Data Model.