Nerivia

Thestral API

Version
1.0.0
Base URL
https://api.nerivia.io/v1/thestral/neripay

Guide

Overview

Thestral is Nerivia's REST API for external integrations: one HTTPS host, JSON bodies, and one signing scheme for every product. Nerivia is non-custodial and never holds your funds.

Authentication

Thestral signs every request instead of using bearer tokens, so a captured request can't be replayed or altered. Each API key has two values:

  • api_key_uuid: the key's public ID, sent with every request.
  • api_key_signing_secret: the secret you sign with. It's shown once, when you create the key, and never sent to Nerivia again.

Send these three headers with every request:

Header Value
X-Nerivia-Key-Id Your api_key_uuid.
X-Nerivia-Timestamp Current Unix time, in seconds.
X-Nerivia-Signature Lowercase hex HMAC-SHA256 of the signed message, keyed with your api_key_signing_secret.

The signed message is the timestamp, a period, and the raw request body, in UTF-8:

<timestamp>.<raw_body>
  • Sign the exact bytes you send. Any difference, even whitespace or key order, fails the check.
  • A request with no body signs <timestamp>. alone.
  • The timestamp must be within five minutes of server time, so keep your clock in sync.

A bad signature, a stale timestamp, a revoked or expired key, or a suspended workspace returns 401 with a specific error code. Revoke a key or set its expiry in the Nerivia dashboard.

Workspaces

A workspace owns your settings, API keys, and orders, and nothing crosses between workspaces. Every account has two:

  • Live: real payments.
  • Test: the same flows on test networks, to rehearse your integration.

Each API key belongs to one workspace, and Nerivia resolves the workspace from that key: no URL or body names it. To switch between test and live, sign with the other workspace's key.

Errors

Every error returns the same shape:

JSON
{
  "errors": [
    {
      "code": "neripay_order_amount_out_of_range",
      "field": null,
      "message": "The order amount is outside the accepted range."
    }
  ]
}
  • code: a stable, machine-readable ID. Branch on it, never on the message.
  • field: the request field that caused the error, or null.
  • message: a readable explanation in the Accept-Language language, English or Spanish.

The errors list holds one item per problem. The status code gives the class of failure: 400 for an invalid request, 401 for an authentication failure, 403 for a permission failure, and 404 for an object the request references that doesn't exist in your workspace.

Webhooks

Instead of polling, register an endpoint URL in the dashboard and choose the events it receives. Each subscription gets its own signing secret.

Nerivia POSTs a JSON body to your endpoint, signed the same way as a request: X-Nerivia-Timestamp and X-Nerivia-Signature, computed over the exact body delivered, with that subscription's secret. Verify the signature before trusting a delivery, and reply with any 2xx status to acknowledge it. A non-2xx reply or a timeout is retried a limited number of times.

Support

Need help? Message us on WhatsApp at +593 963 187 317.

Resource

Asset ledger configs

An asset ledger config is one asset on one ledger, or blockchain network, that your workspace accepts, such as USDT on Polygon, with its receiving address, commission rate, and amount limits. You set configs up in the dashboard, and the API reads them.

GETList asset ledger configs

/workspace-config/asset-ledger-configs/

Returns your workspace's active asset ledger configs, newest first: every asset and ledger pair you can create orders in right now. Inactive configs never appear, and no filter can include them.

Filter by asset or ledger with the UUIDs inside an item's asset_ledger object, never with the config's own uuid. When you combine filters, an item must match all of them, and a value the API can't parse, such as a malformed UUID, returns an empty list, never the unfiltered one.

A workspace with no active config gets a 200 with an empty results list: set one up in the dashboard before creating orders.

Request

Parameters
assetstring (uuid)

Only configs for this asset uuid, on every ledger it's set up on.

ledgerstring (uuid)

Only configs on this ledger uuid, for every asset set up on it.

limitinteger

Items per page. Defaults to 10, which also applies when the value is invalid.

offsetinteger

Items to skip before the page starts. Defaults to 0, which also applies when the value is invalid.

Responses

200

Your active asset ledger configs.

countinteger

Items matching your filters, across every page.

nextstring | null (uri)

URL of the next page, or null on the last page.

previousstring | null (uri)

URL of the previous page, or null on the first page.

resultsarray

This page's items, newest first.

uuidstring

The config's ID. Not the value you send when creating an order.

is_activeboolean

Whether the pair accepts orders. Always true here.

commission_ratestring (decimal)

Nerivia's commission as a percentage: "2.50" means 2.50%. Each new order keeps the rate in force when it's created.

min_amountstring (decimal)

The smallest order amount accepted, in the asset's units.

max_amountstring (decimal)

The largest order amount accepted, in the asset's units.

receiving_addressstring

Where your share of each settled order is sent. Check it after any dashboard change.

asset_ledgerobject

The asset and ledger this config is for.

uuidstring

ID of the asset and ledger pair. Send it as asset_ledger when you create an order.

contract_addressstring | null

The token's contract address on this ledger, or null for the ledger's native asset. It is not where a customer pays.

assetobject

The asset, such as Tether USD.

uuidstring

The asset's ID.

namestring

The asset's name, such as Tether USD.

codestring

The asset's code, such as USDT.

decimalsinteger

Decimal places the asset supports, which caps an order amount's precision.

ledgerobject

The ledger, or blockchain network, such as Polygon.

uuidstring

The ledger's ID.

namestring

The ledger's name, such as Polygon Amoy.

codestring

The ledger's code, such as polygon-amoy.

address_regexstring | null

The pattern an address on this ledger must match, or null when unknown.

ExampleJSON
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "uuid": "59a13b02-a4b5-4d42-9d20-19d42be990e9",
      "is_active": true,
      "commission_rate": "2.50",
      "min_amount": "1.000000000000000000",
      "max_amount": "10000.000000000000000000",
      "receiving_address": "0xf59fedB5D38CD00995AC1D8256f4CfeF46FD58a3",
      "asset_ledger": {
        "uuid": "37caa3f8-79f3-48a3-bde2-840636f50df2",
        "contract_address": "0x0502986e4Be5d3e0A98D68A0fD0f7683F9968843",
        "asset": {
          "uuid": "46588bb4-600b-4e41-a5c0-95071166f41d",
          "name": "Tether USD",
          "code": "USDT",
          "decimals": 2
        },
        "ledger": {
          "uuid": "85a198fd-4ee6-4f17-bbeb-040ff46896dc",
          "name": "Polygon Amoy",
          "code": "polygon-amoy",
          "address_regex": "^0x[0-9a-fA-F]{40}$"
        }
      }
    }
  ]
}
401

Authentication failed: a bad signature, a stale timestamp, a revoked or expired key, or a suspended workspace.

errorsarray

One item per problem.

codestring

A stable, machine-readable error ID. Branch on it, never on message.

fieldstring | null

The request field that caused the error, or null.

messagestring

A readable explanation in the Accept-Language language.

403

The key isn't allowed to perform this action.

errorsarray

One item per problem.

codestring

A stable, machine-readable error ID. Branch on it, never on message.

fieldstring | null

The request field that caused the error, or null.

messagestring

A readable explanation in the Accept-Language language.

Resource

Orders

An order asks a customer to pay an amount in one asset on one ledger, to an address dedicated to that order. It moves through these statuses on its own:

Status Meaning
awaiting_payment Created, and waiting for the customer's payment until expires_at.
paid Payment confirmed on-chain. Fulfill the order at this point.
settling Nerivia is sending the funds to your receiving address.
completed The funds reached your receiving address.
expired No payment arrived before expires_at.
settlement_failed Sending the funds to your receiving address failed.

Subscribe to the neripay.order.status.change webhook event to follow these changes, or poll List orders with the order's uuid as a filter.

GETList orders

/orders/

Returns your workspace's orders, newest first.

Filter on created_at with the two date parameters, whose bounds are inclusive; the field itself isn't returned. When you combine filters, an order must match all of them, and a value the API can't parse, such as a malformed UUID, returns an empty list, never the unfiltered one.

List items carry no checkout_url: read it from the creation response.

Request

Parameters
statusstring

Only orders in this status.

uuidstring (uuid)

Only the order with this ID.

created_at__gtestring (date-time)

Only orders created at or after this moment. A value with no offset is read as UTC.

created_at__ltestring (date-time)

Only orders created at or before this moment. A value with no offset is read as UTC.

limitinteger

Items per page. Defaults to 10, which also applies when the value is invalid.

offsetinteger

Items to skip before the page starts. Defaults to 0, which also applies when the value is invalid.

Responses

200

Your orders.

countinteger

Items matching your filters, across every page.

nextstring | null (uri)

URL of the next page, or null on the last page.

previousstring | null (uri)

URL of the previous page, or null on the first page.

resultsarray

This page's items, newest first.

uuidstring

The order's ID. Store it to find the order later with the uuid filter.

amountstring (decimal)

What the customer pays, in the asset's units. Nerivia's commission comes out of it, not on top of it.

commission_ratestring (decimal)

Nerivia's commission as a percentage, fixed when the order was created.

statusstring

The order's current status, such as awaiting_payment or paid.

expires_atstring (date-time)

When the order stops accepting payment. Drive your countdown from it rather than assuming a fixed window.

contract_addressstring

The order's own settlement address, where the customer pays. Use it for this order only.

asset_ledgerobject

The asset and ledger the order is priced and paid in.

uuidstring

ID of the asset and ledger pair.

assetobject

The asset, such as Tether USD.

uuidstring

The asset's ID.

namestring

The asset's name, such as Tether USD.

codestring

The asset's code, such as USDT.

decimalsinteger

Decimal places the asset supports, which caps an order amount's precision.

ledgerobject

The ledger, or blockchain network, such as Polygon.

uuidstring

The ledger's ID.

namestring

The ledger's name, such as Polygon Amoy.

codestring

The ledger's code, such as polygon-amoy.

address_regexstring | null

The pattern an address on this ledger must match, or null when unknown.

contract_addressstring | null

The token's contract address on this ledger, or null for the ledger's native asset. It is not where a customer pays.

external_referencestring | null

Your own ID for the order, or null for an order created in the dashboard.

ExampleJSON
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "uuid": "e75f7105-d903-4d69-b1ea-17bbfbd7f777",
      "amount": "10.000000000000000000",
      "commission_rate": "2.50",
      "status": "settlement_failed",
      "expires_at": "2026-09-11T05:44:18.988829Z",
      "contract_address": "0x0146a0AA378044be8a59e2aee97B00Cac073539C",
      "asset_ledger": {
        "uuid": "37caa3f8-79f3-48a3-bde2-840636f50df2",
        "asset": {
          "uuid": "46588bb4-600b-4e41-a5c0-95071166f41d",
          "name": "Tether USD",
          "code": "USDT",
          "decimals": 2
        },
        "ledger": {
          "uuid": "85a198fd-4ee6-4f17-bbeb-040ff46896dc",
          "name": "Polygon Amoy",
          "code": "polygon-amoy",
          "address_regex": "^0x[0-9a-fA-F]{40}$"
        },
        "contract_address": "0x0502986e4Be5d3e0A98D68A0fD0f7683F9968843"
      },
      "external_reference": null
    }
  ]
}
401

Authentication failed: a bad signature, a stale timestamp, a revoked or expired key, or a suspended workspace.

errorsarray

One item per problem.

codestring

A stable, machine-readable error ID. Branch on it, never on message.

fieldstring | null

The request field that caused the error, or null.

messagestring

A readable explanation in the Accept-Language language.

403

The key isn't allowed to perform this action.

errorsarray

One item per problem.

codestring

A stable, machine-readable error ID. Branch on it, never on message.

fieldstring | null

The request field that caused the error, or null.

messagestring

A readable explanation in the Accept-Language language.

POSTCreate order

/orders/

Creates a payment order for an amount in one asset on one ledger. Nerivia gives the order its own settlement address, starts watching it, and returns the order with a checkout_url: a hosted payment page you can send your customer to instead of building your own.

A new order starts in awaiting_payment, and its payment window opens as soon as this call succeeds.

After creating

Show your customer contract_address and amount, or send them to checkout_url. Nerivia confirms the payment, marks the order paid, sends the funds to your receiving address, and marks it completed, with no further call from you.

Fulfill on paid, not completed: paid means your customer has paid, while completed only means the funds have reached you.

Request

Body

The order to create. All three fields are required, and any other field is ignored.

asset_ledgerstringRequired

The asset_ledger.uuid of an active asset ledger config in your key's workspace.

amountstring (decimal)Required

What the customer pays, as a decimal string in the asset's units, such as "25.50". It must fall within the config's min_amount and max_amount, carry no more decimals than the asset supports, and hold at most 36 digits and 18 decimals.

external_referencestringRequired

Your own ID for the order, such as an invoice number. Up to 36 characters, and unique in your workspace, so a retried creation never duplicates a charge.

ExampleJSON
{
  "asset_ledger": "37caa3f8-79f3-48a3-bde2-840636f50df2",
  "amount": "100.00",
  "external_reference": "AAA-000-000-003"
}

Responses

201

The created order.

uuidstring

The order's ID. Store it to find the order later with the uuid filter.

amountstring (decimal)

What the customer pays, in the asset's units. Nerivia's commission comes out of it, not on top of it.

commission_ratestring (decimal)

Nerivia's commission as a percentage, fixed when the order was created.

statusstring

The order's current status, such as awaiting_payment or paid.

expires_atstring (date-time)

When the order stops accepting payment. Drive your countdown from it rather than assuming a fixed window.

contract_addressstring

The order's own settlement address, where the customer pays. Use it for this order only.

asset_ledgerobject

The asset and ledger the order is priced and paid in.

uuidstring

ID of the asset and ledger pair.

assetobject

The asset, such as Tether USD.

uuidstring

The asset's ID.

namestring

The asset's name, such as Tether USD.

codestring

The asset's code, such as USDT.

decimalsinteger

Decimal places the asset supports, which caps an order amount's precision.

ledgerobject

The ledger, or blockchain network, such as Polygon.

uuidstring

The ledger's ID.

namestring

The ledger's name, such as Polygon Amoy.

codestring

The ledger's code, such as polygon-amoy.

address_regexstring | null

The pattern an address on this ledger must match, or null when unknown.

contract_addressstring | null

The token's contract address on this ledger, or null for the ledger's native asset. It is not where a customer pays.

external_referencestring

Your own ID for the order, as you sent it.

checkout_urlstring (uri)

A Nerivia-hosted payment page for this order alone, safe to share with your customer.

ExampleJSON
{
  "uuid": "9ba6ade8-416a-495b-8cf6-6eeac215ab08",
  "amount": "100.000000000000000000",
  "commission_rate": "2.50",
  "status": "awaiting_payment",
  "expires_at": "2026-09-11T21:45:03.204571Z",
  "contract_address": "0x23BDBDbAD94Bb5CD2D8AD44645523D4A5Bd1aeD9",
  "asset_ledger": {
    "uuid": "37caa3f8-79f3-48a3-bde2-840636f50df2",
    "asset": {
      "uuid": "46588bb4-600b-4e41-a5c0-95071166f41d",
      "name": "Tether USD",
      "code": "USDT",
      "decimals": 2
    },
    "ledger": {
      "uuid": "85a198fd-4ee6-4f17-bbeb-040ff46896dc",
      "name": "Polygon Amoy",
      "code": "polygon-amoy",
      "address_regex": "^0x[0-9a-fA-F]{40}$"
    },
    "contract_address": "0x0502986e4Be5d3e0A98D68A0fD0f7683F9968843"
  },
  "external_reference": "AAA-000-000-001",
  "checkout_url": "https://app.nerivia.io/neripay/checkout/9ba6ade8-416a-495b-8cf6-6eeac215ab08"
}
400

The request is invalid. errors lists every problem.

errorsarray

One item per problem.

codestring

A stable, machine-readable error ID. Branch on it, never on message.

fieldstring | null

The request field that caused the error, or null.

messagestring

A readable explanation in the Accept-Language language.

ExampleJSON
{
  "errors": [
    {
      "code": "neripay_order_amount_out_of_range",
      "field": null,
      "message": "The order amount is outside the accepted range."
    }
  ]
}
401

Authentication failed: a bad signature, a stale timestamp, a revoked or expired key, or a suspended workspace.

errorsarray

One item per problem.

codestring

A stable, machine-readable error ID. Branch on it, never on message.

fieldstring | null

The request field that caused the error, or null.

messagestring

A readable explanation in the Accept-Language language.

403

The key isn't allowed to perform this action.

errorsarray

One item per problem.

codestring

A stable, machine-readable error ID. Branch on it, never on message.

fieldstring | null

The request field that caused the error, or null.

messagestring

A readable explanation in the Accept-Language language.

404

An object the request references doesn't exist in your workspace.

errorsarray

One item per problem.

codestring

A stable, machine-readable error ID. Branch on it, never on message.

fieldstring | null

The request field that caused the error, or null.

messagestring

A readable explanation in the Accept-Language language.