API

Version: v1

Authentication

Set of endpoints for authenticating against Relayer's API and to request permissioned access for other endpoint scopes.

Get a unique nonce

GET /v1/auth/nonce

Retrieve a unique nonce to include in a SIWx (“Sign-In with X”) message for authenticating on-chain accounts via the "siwx" grant type.

Response

A unique alphanumeric nonce (string) Example response:

"8og0j9nt5vp74my1"

Get an app access token using the "Client Credentials" grant type

POST /v1/auth/token

Retrieve an application access token via the “Client Credentials” grant type. This authentication method is intended for server-to-server interaction with a confidential client.

Headers

Name
Value

Content-Type

application/x-www-form-urlencoded

Authorization

Basic <base64 encoded "client_id:client_secret">

Request

Data application/x-www-form-urlencoded

  • grant_type (string) required Method of authentication. Value: "client_credentials"

  • scope (string) String listing requested scopes that are separated by spaces. See Scopes for the list of scopes. If no scope if provided, the default scope will be authorized. Example value: "users users.accounts users.accounts.attestation users.enrollment rewards"

Response

Error responses for the /v1/auth/token endpoint differ from Relayer defined error responses and conform to the response defined by RFC-6749 (section 5.2).

The application access token (object)

  • access_token (string) required Example: ”eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c”

  • token_type (string) required The type of token used in the Authorization header. Example: "Bearer"

  • expires_in (integer) required Number of seconds until the access token expires and a new access token will need to be requested. Example: 3600

  • scope (string) String listing authorized scopes that were requested. Scopes are separated by spaces. Example: "users users.accounts users.accounts.attestation users.enrollment rewards"

Example response:

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "users users.accounts users.accounts.attestation users.enrollment rewards"
}

Get a user access token using the "Sign-In With X" grant type

POST /v1/auth/token

Retrieve an application access token either via the “SIWX (Sign-In With X)” grant type. This authentication method is intended for communication between a public client and server.

Headers

Name
Value

Content-Type

application/x-www-form-urlencoded

Authorization

Basic <base64 encoded "client_id:client_secret">

Request

Data application/x-www-form-urlencoded

  • grant_type (string) required Method of authentication. Value: "siwx"

  • cacao (string) required Base64URL encoded Chain Agnostic Capability Object (CAIP-74: CACAO) that contains the signing payload and signature of the authenticating account. See CACAO: Chain Agnostic Capability Object for more information.

  • scope (string) String listing requested scopes that are separated by spaces. See Scopes for the list of scopes. If no scope if provided, the default scope will be authorized. Example value: "users.me rewards users users.enrollment users.accounts"

Response

Error responses for the /v1/auth/token endpoint differ from Relayer defined error responses and conform to the response defined by RFC-6749 (section 5.2).

The application access token (object)

  • access_token (string) required The issued access to be used in further requests. Example: ”eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c”

  • token_type (string) required The type of token used in the Authorization header for the authorization scheme. Example: "Bearer"

  • expires_in (integer) required Number of seconds until the access token expires and a new access token will need to be requested. Example: 3600

  • refresh_token (string) required Token used to retrieve a new access token using the "Refresh Token" grant type, once an access token has expired. Example: ”eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c”

  • scope (string) required String listing authorized scopes that were requested. Scopes are separated by spaces. Example: "users.me rewards users users.enrollment users.accounts"

  • user_id (string) required The generated ID of the authenticated user. The user ID is under the namespace of the partner making the request. Example: "de1f1af2-82c8-4648-ae05-abd1098c1596"

Example response:

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
    "token_type": "Bearer",
    "expires_in": 3600,
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
    "scope": "users.me rewards users users.enrollment users.accounts",
    "user_id": "de1f1af2-82c8-4648-ae05-abd1098c1596"
}

Get a user access token using the "Refresh Token" grant type

POST /v1/auth/token

Retrieve a new access token via the ”refresh_token” grant type and using the refresh token received from the “SIWX (Sign-In With X)” grant type.

Headers

Name
Value

Content-Type

application/x-www-form-urlencoded

Authorization

Basic <base64 encoded "client_id:client_secret">

Request

Data application/x-www-form-urlencoded

  • grant_type (string) required Method of authentication. Value: "refresh_token"

  • refresh_token (string) required The refresh token returned in response from the "Get a user access token using the "Sign-In With X" grant type. Example value: ”eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c”

Response

Error responses for the /v1/auth/token endpoint differ from Relayer defined error responses and conform to the response defined by RFC-6749 (section 5.2).

The application access token (object)

  • access_token (string) required Example: ”eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c”

  • token_type (string) required The type of token used in the Authorization header. Example: "Bearer"

  • expires_in (integer) required Number of seconds until the access token expires and a new access token will need to be requested. Example: 3600

  • scope (string) required String listing authorized scopes that were requested. Scopes are separated by spaces. Example: "users.me rewards users users.enrollment users.accounts"

Example response:

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
    "token_type": "Bearer",
    "expires_in": 3600,
    "scope": "users.me rewards users users.enrollment users.accounts"
}

Users

Create a new user

POST /v1/users

Create a new Relayer user based on the integrating partner's user ID.

Headers

Name
Value

Content-Type

application/json

Authorization

Bearer <access token>

Request

Body application/json

  • id (string) required The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

  • auto_enroll (boolean) Whether to automatically enroll the user for rewards. If true the user will be enrolled once created, if false the user will not be enrolled. Defaults to false. Example value: false

Response

The Relayer profile of the user (object)

  • id (string) required The ID of the user used by the integrating partner. This is the same as the id included in the request body. Example value: ”67e46f52-8fc9-4224-a8b7-bd9817bc4368”

  • onchain_accounts (list[object]) required List of on-chain accounts connected to the user. Value: []

    • id (string) required The ID of the account assigned by Relayer. Example value: "67e46f52-8fc9-4224-a8b7-bd9817bc4368"

    • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on. Example value: "eip155"

    • namespace (string) required The colloquial name of blockchain class/ecosystem the account is on. Example value: "Ethereum Ecosystem"

    • account_address (string) required The address of the account. Example value: "0x25963d25e2fd2287aeD51009B73db4619051DA3f"

    • account_origin (string) required Whether the account is external or internal to the integrating partner application. This is to distinguish accounts that were created by the client itself and accounts that connected to the client (such as through a wallet extension). Example values:

      • "external"

      • "internal"

  • enrolled (boolean) required Whether the user is currently enrolled for personalized rewards. Value: false

Example response:

{
    "id": "67e46f52-8fc9-4224-a8b7-bd9817bc4368",
    "enrolled": false,
    "onchain_accounts": []
}

Get a user

GET /v1/users/id/{id}

Retrieve a Relayer user by the integrating partner's user ID.

Headers

Name
Value

Authorization

Bearer <access token>

Request

Path

  • id (string) required The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

Response

The Relayer profile of the user (object)

  • id (string) required The ID of the user used by the integrating partner. This is the same as the id included in the request body. Example value: ”67e46f52-8fc9-4224-a8b7-bd9817bc4368”

  • onchain_accounts (list[object]) required List of on-chain accounts connected to the user. Value: []

    • id (string) required The ID of the account assigned by Relayer. Example value: "67e46f52-8fc9-4224-a8b7-bd9817bc4368"

    • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on. Example value: "eip155"

    • namespace (string) required The colloquial name of blockchain class/ecosystem the account is on. Example value: "Ethereum Ecosystem"

    • account_address (string) required The address of the account. Example value: "0x25963d25e2fd2287aeD51009B73db4619051DA3f"

    • account_origin (string) required Whether the account is external or internal to the integrating partner application. This is to distinguish accounts that were created by the client itself and accounts that connected to the client (such as through a wallet extension). Example values:

      • "external"

      • "internal"

  • enrolled (boolean) required Whether the user is currently enrolled for personalized rewards. Example value: false

Example response:

{
    "id": "67e46f52-8fc9-4224-a8b7-bd9817bc4368",
    "enrolled": false,
    "onchain_accounts": [
        {
            "id": "67e46f52-8fc9-4224-a8b7-bd9817bc4368",
            "caip2_namespace": "eip155",
            "namespace": "Ethereum Ecosystem",
            "account_address": "0x25963d25e2fd2287aeD51009B73db4619051DA3f",
            "account_origin": "external"
        }
    ]
}

Get users

GET /v1/users

Retrieve a paginated list of Relayer users created by the integrating partner.

Headers

Name
Value

Authorization

Bearer <access token>

Request

Query

  • continuation (string) Continuation token from a previous response for use in requesting the next page of users.

  • size (integer) The number of users to return in the page response. size can not exceed 10,000. Example value: 10000

Response

  • continuation (string | null) Continuation token to paginate the results of users. The token is null if no next page exists.

  • users (list[object]) required The Relayer profile of the user.

    • id (string) required The ID of the user used by the integrating partner. This is the same as the id included in the request body. Example value: ”67e46f52-8fc9-4224-a8b7-bd9817bc4368”

    • onchain_accounts (list[object]) required List of on-chain accounts connected to the user. Value: []

      • id (string) required The ID of the account assigned by Relayer. Example value: "67e46f52-8fc9-4224-a8b7-bd9817bc4368"

      • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on. Example value: "eip155"

      • namespace (string) required The colloquial name of blockchain class/ecosystem the account is on. Example value: "Ethereum Ecosystem"

      • account_address (string) required The address of the account. Example value: "0x25963d25e2fd2287aeD51009B73db4619051DA3f"

      • account_origin (string) required Whether the account is external or internal to the integrating partner application. This is to distinguish accounts that were created by the client itself and accounts that connected to the client (such as through a wallet extension). Example values:

        • "external"

        • "internal"

    • enrolled (boolean) required Whether the user is currently enrolled for personalized rewards. Example value: false

Example response:

{
    "continuation": "
    "users": [
        {
            "id": "67e46f52-8fc9-4224-a8b7-bd9817bc4368",
            "enrolled": false,
            "onchain_accounts": [
                {
                    "id": "67e46f52-8fc9-4224-a8b7-bd9817bc4368",
                    "caip2_namespace": "eip155",
                    "namespace": "Ethereum Ecosystem",
                    "account_address": "0x25963d25e2fd2287aeD51009B73db4619051DA3f",
                    "account_origin": "external"
                }
            ]
        }
    ]
}

Delete a user

DEL /v1/users/id/{id}

Delete a Relayer user by the integrating partner’s user ID. This includes deleting any accounts added and/or enrolled by the integrating partner.

Headers

Name
Value

Authorization

Bearer <access token>

Request

Path

  • id (string) required

    The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

Response

No content -- the user was successfully deleted.

Get the current user

GET /v1/users/me

Retrieve the currently authenticated Relayer user. This is useful for users that have directly authenticated with Relayer.

Headers

Name
Value

Authorization

Bearer <access token>

Response

The Relayer profile of the user (object)

  • id (string) required The ID of the user used by the integrating partner. This is the same as the id included in the request body. Example value: ”67e46f52-8fc9-4224-a8b7-bd9817bc4368”

  • onchain_accounts (list[object]) required List of on-chain accounts connected to the user. Value: []

    • id (string) required The ID of the account assigned by Relayer. Example value: "67e46f52-8fc9-4224-a8b7-bd9817bc4368"

    • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on. Example value: "eip155"

    • namespace (string) required The colloquial name of blockchain class/ecosystem the account is on. Example value: "Ethereum Ecosystem"

    • account_address (string) required The address of the account. Example value: "0x25963d25e2fd2287aeD51009B73db4619051DA3f"

    • account_origin (string) required Whether the account is external or internal to the integrating partner application. This is to distinguish accounts that were created by the client itself and accounts that connected to the client (such as through a wallet extension). Example values:

      • "external"

      • "internal"

  • enrolled (boolean) required Whether the user is currently enrolled for personalized rewards. Example value: false

Example response:

{
    "id": "67e46f52-8fc9-4224-a8b7-bd9817bc4368",
    "enrolled": false,
    "onchain_accounts": [
        {
            "id": "67e46f52-8fc9-4224-a8b7-bd9817bc4368",
            "caip2_namespace": "eip155",
            "namespace": "Ethereum Ecosystem",
            "account_address": "0x25963d25e2fd2287aeD51009B73db4619051DA3f",
            "account_origin": "external"    
        }
    ]
}

Accounts

Attest an on-chain account for a user

POST /v1/users/id/{id}/accounts/onchain/attestation

Attest that an account should be added to a specific user. The account origin will be "internal" to the integrating partner.

Headers

Name
Value

Content-Type

application/json

Authorization

Bearer <access token>

Request

Path

  • id (string) required

    The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

Body application/json

  • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on. Example value: "eip155"

  • account_address (string) required The address of the account. Example value: "0x25963d25e2fd2287aeD51009B73db4619051DA3f"

Response

No content -- the account was successfully added.

Connect an on-chain account to a user

POST /v1/users/id/{id}/accounts/onchain

Add a new account to a specific user.

Headers

Name
Value

Content-Type

application/json

Authorization

Bearer <access token>

Request

Path

  • id (string) required

    The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

Body application/json

  • account_origin (string) required Whether the account is external or internal to the integrating partner application. This is to distinguish accounts that were created by the application itself and accounts that connected to the application (such as through a wallet extension). Example values:

    • "external"

    • "internal"

  • cacao (object) required Chain Agnostic Capability Object (CAIP-74: CACAO) that contains the signing payload and signature of the authenticating account. See CACAO: Chain Agnostic Capability Object for more information.

Response

No content -- the account was successfully added.

Disconnect an account from a user

DEL /v1/users/id/{id}/accounts/{account_id}

Remove an existing account from a specific user.

Headers

Name
Value

Content-Type

application/json

Authorization

Bearer <access token>

Request

Path

  • id (string) required

    The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

  • account_id (string) required The identifier of the account used by Relayer. Example value: "468c6a73-9e25-479d-8cc6-9a837536f260"

Response

No content -- the account was successfully removed.

Get connected accounts for a user

GET /v1/users/id/{id}/accounts

Remove an existing account from a specific user.

Headers

Name
Value

Content-Type

application/json

Authorization

Bearer <access token>

Request

Path

  • id (string) required

    The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

Response

The accounts added to the user (list[object])

  • id (string) required The ID of the account assigned by Relayer. Example value: "67e46f52-8fc9-4224-a8b7-bd9817bc4368"

  • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on. Example value: "eip155"

  • namespace (string) required The colloquial name of blockchain class/ecosystem the account is on. Example value: "Ethereum Ecosystem"

  • account_address (string) required The address of the account. Example value: "0x25963d25e2fd2287aeD51009B73db4619051DA3f"

  • account_origin (string) required Whether the account is external or internal to the integrating partner application. This is to distinguish accounts that were created by the client itself and accounts that connected to the client (such as through a wallet extension). Example values:

    • "external"

    • "internal"

Example response:

[
    {
        "account_id": "67e46f52-8fc9-4224-a8b7-bd9817bc4368",
        "chain_id": "0x1",
        "chain_name": "ethereum",
        "address": "0x25963d25e2fd2287aeD51009B73db4619051DA3f",
        "account_origin": "external"
    }
]

Enrollment

Enroll a user

POST /v1/users/id/{id}/enrollment

Enroll a user by integrating partner ID for personalized rewards.

Headers

Name
Value

Authorization

Bearer <access token>

Request

Path

  • id (string) required

    The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

Response

The user was successfully enrolled

Unenroll a user

DEL /v1/users/id/{id}/enrollment

Unenroll a user by integrating partner ID from personalized rewards.

Headers

Name
Value

Authorization

Bearer <access token>

Request

Path

  • id (string) required

    The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

Response

The user was successfully unenrolled

Get enrollment status for user

GET /v1/users/id/{id}/enrollment

Retrieve the enrollment status for a user.

Headers

Name
Value

Authorization

Bearer <access token>

Request

Path

  • id (string) required

    The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

Response

The enrollment status for the user (object)

  • enrolled (boolean) Whether the user is currently enrolled in personalized rewards.

Example response:

{
    "enrolled": true
}

Reward Feeds

Get promotional rewards

GET /v1/rewards

Retrieve non-curated rewards for promotional use by the integrating partner.

Headers

Name
Value

Authorization

Basic <base64 encoded "client_id:client_secret">

Response

The rewards feed for promotion (list[object])

  • id (string) required ID of the reward. Example value: "603d000a-f635-4cae-902c-ce3c077dcb9f"

  • placement (integer) required The placement index for the reward in the feed. Example value: 0

  • single_use (boolean) required Whether the offer is usable more than once. Example value: true

  • number_of_uses (integer) required Number of times the reward can be used. Example value: 1

  • type (string) required The type of the reward. Example values (non-extensive):

    • "eCommerce"

    • "DEX"

    • "Bridge"

  • short_description (string) required Short description for the reward.

  • full_description (string) required Full description for the reward.

  • min_reward_amount (number) required Minimum reward amount.

  • max_reward_amount (number) required Maximum reward amount.

  • reward_asset (object) required Currency/token that the reward is paid out in.

    • name (string) required Name of the currency/token.

    • symbol (string) required Symbol of the currency/token.

    • contract_address (string | null) required The address of the token or null if the token is native.

    • chain (object) required The chain information of the token.

      • name (string) required Name of the chain.

      • namespace (string) required The colloquial name of blockchain class/ecosystem the chain is a part of.

      • chain_id (string) required The colloquial chain ID of the blockchain.

      • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on.

      • caip2_reference (string) required The CAIP-2 reference of the blockchain standard/ecosystem the account is on.

      • image_url (string) required URL of the chain's logo.

  • brand (object) required Brand offering the reward.

    • name (string) required Name of the brand.

    • image_url (string) required URL for the brand’s logo.

    • categories (list[string]) required Categories the brand is part of.

    • website_url (string) required Website of the brand.

    • terms_and_conditions (string) required Reward’s terms and conditions.

  • supported_chains (list[object]) required Chains that the offer is supported on.

    • name (string) required Name of the chain.

    • namespace (string) required The colloquial name of blockchain class/ecosystem the chain is a part of.

    • chain_id (string) required The colloquial chain ID of the blockchain.

    • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on.

    • caip2_reference (string) required The CAIP-2 reference of the blockchain standard/ecosystem the account is on.

    • image_url (string) required URL of the chain's logo.

Submit an engagement event for a non-curated reward

POST /v1/rewards/{reward_id}/engage

Submit an engagement event for a non-curated reward.

Headers

Name
Value

Authorization

Basic <base64 encoded "client_id:client_secret">

Request

Path

  • reward_id (string) required The ID of the reward to trigger. Triggering the reward allows the reward to be successfully matched against and be paid out to the user. Example value: "603d000a-f635-4cae-902c-ce3c077dcb9f"

Body application/json

  • event_id (string) required The ID of event (such as a custom event) Example value: "603d000a-f635-4cae-902c-ce3c077dcb9f"

The event was successfully submitted.

Get rewards for a user

GET /v1/users/id/{id}/rewards

Retrieve a personalized rewards feed for a specific user.

Headers

Name
Value

Authorization

Bearer <access token>

Request

Path

  • id (string) required

    The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

Response

The rewards feed for the user (list[object])

  • id (string) required ID of the reward. Example value: "603d000a-f635-4cae-902c-ce3c077dcb9f"

  • placement (integer) required The placement index for the reward in the feed. Example value: 0

  • single_use (boolean) required Whether the offer is usable more than once. Example value: true

  • number_of_uses (integer) required Number of times the reward can be used. Example value: 1

  • type (string) required The type of the reward. Example values (non-extensive):

    • "eCommerce"

    • "DEX"

    • "Bridge"

  • short_description (string) required Short description for the reward.

  • full_description (string) required Full description for the reward.

  • min_reward_amount (number) required Minimum reward amount.

  • max_reward_amount (number) required Maximum reward amount.

  • reward_asset (object) required Currency/token that the reward is paid out in.

    • name (string) required Name of the currency/token.

    • symbol (string) required Symbol of the currency/token.

    • contract_address (string | null) required The address of the token or null if the token is native.

    • chain (object) required The chain information of the token.

      • name (string) required Name of the chain.

      • namespace (string) required The colloquial name of blockchain class/ecosystem the chain is a part of.

      • chain_id (string) required The colloquial chain ID of the blockchain.

      • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on.

      • caip2_reference (string) required The CAIP-2 reference of the blockchain standard/ecosystem the account is on.

      • image_url (string) required URL of the chain's logo.

  • brand (object) required Brand offering the reward.

    • name (string) required Name of the brand.

    • image_url (string) required URL for the brand’s logo.

    • categories (list[string]) required Categories the brand is part of.

    • website_url (string) required Website of the brand.

    • terms_and_conditions (string) required Reward’s terms and conditions.

  • supported_chains (list[object]) required Chains that the offer is supported on.

    • name (string) required Name of the chain.

    • namespace (string) required The colloquial name of blockchain class/ecosystem the chain is a part of.

    • chain_id (string) required The colloquial chain ID of the blockchain.

    • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on.

    • caip2_reference (string) required The CAIP-2 reference of the blockchain standard/ecosystem the account is on.

    • image_url (string) required URL of the chain's logo.

  • triggered (boolean) required Whether the offer is currently activated.

  • redeemed (boolean) required Whether the offer was completed.

Trigger a reward for redemption by a user

POST /v1/users/id/{id}/rewards/{reward_id}/trigger

Trigger a reward for redemption by a user using a specified trigger method. Triggering a reward allows the reward to be successfully matched and paid out to the user. A reward may be triggered in multiple ways across an application. The trigger ID is used to differentiate these trigger types.

Headers

Name
Value

Authorization

Bearer <access token>

Request

Path

  • id (string) required

    The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

  • reward_id (string) required The ID of the reward to trigger. Triggering the reward allows the reward to be successfully matched against and be paid out to the user. Example value: "603d000a-f635-4cae-902c-ce3c077dcb9f"

Body application/json

  • trigger_id (string) required ID of the trigger event. Example value: "603d000a-f635-4cae-902c-ce3c077dcb9f"

Response

The reward that was triggered (object)

  • id (string) required ID of the reward. Example value: "603d000a-f635-4cae-902c-ce3c077dcb9f"

  • placement (integer) required The placement index for the reward in the feed. Example value: 0

  • single_use (boolean) required Whether the offer is usable more than once. Example value: true

  • number_of_uses (integer) required Number of times the reward can be used. Example value: 1

  • type (string) required The type of the reward. Example values (non-extensive):

    • "eCommerce"

    • "DEX"

    • "Bridge"

  • short_description (string) required Short description for the reward.

  • full_description (string) required Full description for the reward.

  • min_reward_amount (number) required Minimum reward amount.

  • max_reward_amount (number) required Maximum reward amount.

  • reward_asset (object) required Currency/token that the reward is paid out in.

    • name (string) required Name of the currency/token.

    • symbol (string) required Symbol of the currency/token.

    • contract_address (string | null) required The address of the token or null if the token is native.

    • chain (object) required The chain information of the token.

      • name (string) required Name of the chain.

      • namespace (string) required The colloquial name of blockchain class/ecosystem the chain is a part of.

      • chain_id (string) required The colloquial chain ID of the blockchain.

      • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on.

      • caip2_reference (string) required The CAIP-2 reference of the blockchain standard/ecosystem the account is on.

      • image_url (string) required URL of the chain's logo.

  • brand (object) required Brand offering the reward.

    • name (string) required Name of the brand.

    • image_url (string) required URL for the brand’s logo.

    • categories (list[string]) required Categories the brand is part of.

    • website_url (string) required Website of the brand.

    • terms_and_conditions (string) required Reward’s terms and conditions.

  • supported_chains (list[object]) required Chains that the offer is supported on.

    • name (string) required Name of the chain.

    • namespace (string) required The colloquial name of blockchain class/ecosystem the chain is a part of.

    • chain_id (string) required The colloquial chain ID of the blockchain.

    • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on.

    • caip2_reference (string) required The CAIP-2 reference of the blockchain standard/ecosystem the account is on.

    • image_url (string) required URL of the chain's logo.

  • triggered (boolean) required Whether the offer is currently activated. Value: true

  • redeemed (boolean) required Whether the offer was completed.

Submit a reward engagement event for a user

POST /v1/users/id/{id}/rewards/{reward_id}/engage

Submit a reward engagement event for a specific user.

Headers

Name
Value

Content-Type

application/json

Authorization

Bearer <access token>

Request

Path

  • id (string) required

    The ID of the user used by the integrating partner. This user ID is under the namespace of the partner making the request. Example values:

    • "john@doc.com"

    • "42"

    • "468c6a73-9e25-479d-8cc6-9a837536f260"

  • reward_id (string) required The ID of the reward to trigger. Triggering the reward allows the reward to be successfully matched against and be paid out to the user. Example value: "603d000a-f635-4cae-902c-ce3c077dcb9f"

Body application/json

  • event_id (string) required The ID of event (such as a custom event) Example value: "603d000a-f635-4cae-902c-ce3c077dcb9f"

Response

The event was successfully submitted.

Rewards

CHANNEL /v1/ws rewards

The rewards channel streams reward status events for a user, such as when a reward has been triggered or redeemed.

Subscribe Request

Message Body application/json

  • method (string) required The request's method. Value: "subscribe"

  • params (object) required Parameters associated with the method call.

    • channel (string) required The channel to subscribe to. Value: "rewards"

    • user_id (string) required The ID of the user to listen to reward status events for. Value: "603d000a-f635-4cae-902c-ce3c077dcb9f"

    • access_token (string) required Access token received from authenticating.

  • request_id (string) Optional client originating request ID sent as an acknowledgement in response.

Subscribe Request Acknowledgement Response

Object sent in response to acknowledge the subscribe request.

Message Body application/json

  • method (string) required The request's method. Value: "subscribe"

  • result (object) Parameters associated with the method call.

    • channel (string) required The channel to subscribe to. Value: "rewards"

  • request_id (string) Optional client originating request ID sent as an acknowledgement in response.

Subscription Response

Subscription events sent across the channel.

Message Body application/json

  • channel (string) required The subscription channel. Value: "rewards"

  • data (object) required Data included in the event -- the reward that object which reflects the status change.

    • id (string) required ID of the reward. Example value: "603d000a-f635-4cae-902c-ce3c077dcb9f"

    • placement (integer) required The placement index for the reward in the feed. Example value: 0

    • single_use (boolean) required Whether the offer is usable more than once. Example value: true

    • number_of_uses (integer) required Number of times the reward can be used. Example value: 1

    • type (string) required The type of the reward. Example values (non-extensive):

      • "eCommerce"

      • "DEX"

      • "Bridge"

    • short_description (string) required Short description for the reward.

    • full_description (string) required Full description for the reward.

    • min_reward_amount (number) required Minimum reward amount.

    • max_reward_amount (number) required Maximum reward amount.

    • reward_asset (object) required Currency/token that the reward is paid out in.

      • name (string) required Name of the currency/token.

        • symbol (string) required Symbol of the currency/token.

        • contract_address (string | null) required The address of the token or null if the token is native.

        • chain (object) required The chain information of the token.

          • name (string) required Name of the chain.

          • namespace (string) required The colloquial name of blockchain class/ecosystem the chain is a part of.

          • chain_id (string) required The colloquial chain ID of the blockchain.

          • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on.

          • caip2_reference (string) required The CAIP-2 reference of the blockchain standard/ecosystem the account is on.

          • image_url (string) required URL of the chain's logo.

    • brand (object) required Brand offering the reward.

      • name (string) required Name of the brand.

      • image_url (string) required URL for the brand’s logo.

      • categories (list[string]) required Categories the brand is part of.

      • website_url (string) required Website of the brand.

      • terms_and_conditions (string) required Reward’s terms and conditions.

    • supported_chains (list[object]) required Chains that the offer is supported on.

      • name (string) required Name of the chain.

      • namespace (string) required The colloquial name of blockchain class/ecosystem the chain is a part of.

      • chain_id (string) required The colloquial chain ID of the blockchain.

      • caip2_namespace (string) required The CAIP-2 namespace of the blockchain standard/ecosystem the account is on.

      • caip2_reference (string) required The CAIP-2 reference of the blockchain standard/ecosystem the account is on.

      • image_url (string) required URL of the chain's logo.

    • triggered (boolean) required Whether the offer is currently activated.

    • redeemed (boolean) required Whether the offer was completed.

Close Frame Response

code (integer) The code of the websocket response. Value: 1000

reason (string) The reason for the websocket closure. Value: ""

Operational

Ping

REQUEST /v1/ws ping

Ping the server to verify the connection is alive and the server will respond with pong.

Request

Message Body application/json

  • method (string) required The request's method. Value: "ping"

  • request_id (string) Optional client originating request ID sent as an acknowledgement in response.

Response

Object sent in response to acknowledge the request.

Body application/json

  • method (string) required The request's method. Value: "pong"

  • request_id (string) Optional client originating request ID sent as an acknowledgement in response.

Close Frame Response

code (integer) The code of the websocket response. Value: 1000

reason (string) The reason for the websocket closure. Value: ""

Heartbeat

CHANNEL /ws heartbeat

The heartbeat verifies that the connection is alive. Heartbeat messages are sent approximately once every second in the absence of any other channel updates.

Update Response

Message Body application/json

  • channel (string) required The request's method. Value: "heartbeat"

Close Frame Response

code (integer) The code of the websocket response. Value: 1000

reason (string) The reason for the websocket closure. Value: ""

Scopes

The following table outlines scopes and the endpoints that are authorized for usage when the scope is granted.

Scope
Authorized Endpoints
Authorized Token Types

(no scope) Grants available by default.

users Grants read, write, and delete access to user profiles created by the integrating partner application. This scope does not include users.me.

  • App token

users.accounts Grants read, write, and delete access to the connected accounts of a user.

  • App token

  • User token

users.accounts.attestation Grants access to attest an on-chain account for a user.

  • App token

users.enrollment Grants read, write, and delete access to a user's enrollment.

  • App token

  • User token

users.me Grants read access to the current user.

  • User token

rewards Grants access to retrieve and interact with rewards.

  • App token

  • User token

CACAO: Chain Agnostic Capability Object

For authenticating and authorizing on-chain accounts, Relayer utilizes CAIP-74 and CAIP-122 standards. CAIP-74 defines a chain-agnostic data model for authentication. This data model encompasses the signing algorithm, the signing payload, and the resulting signature into a single container. CAIP-122 expands on CAIP-74 by defining a specific payload format intended to generalize the message format of EIP-4361. Relayer currently supports the "eip4361" and "caip122" payload types, but is working to support other payload formats, such as Web3Auth's SIWW ("Signin with Web3") and it's package "@web3auth/sign-in-with-web3". These payload formats are intended to be serializable into a message that can be presented and signed by the end user as needed.

For endpoints that require a CACAO, Relayer expects a JSON structure similar to the one below. The keys "h", "p", and "s" correspond to the "Header", "Payload", and "Signature" sub-structures. The CAIP-74 proposal provides more information on these specific structures and their fields, such as their expected data types, formats, and optionality. The payload used in this example is the "eip4361" type.

{
  "h": {
    "t": "eip4361"
  },
  "p": {
    "aud": "http://localhost:3000/login",
    "exp": "2022-03-10T18:09:21.481+03:00",
    "iat": "2022-03-10T17:09:21.481+03:00",
    "iss": "did:pkh:eip155:1:0xBAc675C310721717Cd4A37F6cbeA1F081b1C2a07",
    "nbf": "2022-03-10T17:09:21.481+03:00",
    "nonce": "328917",
    "domain": "localhost:3000",
    "version": "1",
    "requestId": "request-id-random",
    "resources": [
      "ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq",
      "https://example.com/my-web2-claim.json"
    ],
    "statement": "I accept the ServiceOrg Terms of Service: https://service.org/tos"
  },
  "s": {
    "s": "5ccb134ad3d874cbb40a32b399549cd32c953dc5dc87dc64624a3e3dc0684d7d4833043dd7e9f4a6894853f8dc555f97bc7e3c7dd3fcc66409eb982bff3a44671b",
    "t": "eip191"
  }
}

For authenticating with the "siwx" grant type, a Base64 encoded CACAO is required. In JavaScript, this can be created using the following code:

const cacao = {
  "h": {
    "t": "eip4361"
  },
  "p": {
    "aud": "http://localhost:3000/login",
    "exp": "2022-03-10T18:09:21.481+03:00",
    "iat": "2022-03-10T17:09:21.481+03:00",
    "iss": "did:pkh:eip155:1:0xBAc675C310721717Cd4A37F6cbeA1F081b1C2a07",
    "nbf": "2022-03-10T17:09:21.481+03:00",
    "nonce": "328917",
    "domain": "localhost:3000",
    "version": "1",
    "requestId": "request-id-random",
    "resources": [
      "ipfs://bafybeiemxf5abjwjbikoz4mc3a3dla6ual3jsgpdr4cjr3oz3evfyavhwq",
      "https://example.com/my-web2-claim.json"
    ],
    "statement": "I accept the ServiceOrg Terms of Service: https://service.org/tos"
  },
  "s": {
    "s": "0x5ccb134ad3d874cbb40a32b399549cd32c953dc5dc87dc64624a3e3dc0684d7d4833043dd7e9f4a6894853f8dc555f97bc7e3c7dd3fcc66409eb982bff3a44671b",
    "t": "eip191"
  }
};
const serializedCacao = JSON.stringify(cacao);
const base64Cacao = Buffer.from(serializedCacao).toString("base64");

To produce the signature included as cacao.s.s, the payload of the CACAO should be used in formatting a message that can be signed by the account as part of authentication. Below is the full message format for the "eip4361" payload with the location of each field in the CACAO:

{cacao.p.domain} wants you to sign in with your Ethereum account:
{cacao.p.iss[address]}

{cacao.p.statement}

URI: {cacao.p.aud}
Version: {cacao.p.version}
Chain ID: {cacao.p.iss[chainId.reference]}
Nonce: {cacao.p.nonce}
Issued At: {cacao.p.iat}
Expiration Time: ${cacao.p.exp}
Not Before: ${cacao.p.nbf}
Request ID: ${cacao.p.requestId}
Resources:
- {cacao.p.resources[0]}
- {cacao.p.resources[1]}
...
- {cacao.p.resources[n]}

The "eip4361" allows for optional payload fields that don't need to be included in the CACAO or reflected in the formatted message. This is the IPLD schema for the "Payload" sub-structure (as outlined in the "CAIP-74: CACAO - Chain Agnostic CApability Object" specification:

type Payload struct {
  domain String // =domain
  iss String // = DID pkh
  aud String // =uri
  version String
  nonce String
  iat String // RFC3339 date-time =issued-at
  nbf optional String // RFC3339 date-time =not-before
  exp optional String // RFC3339 date-time = expiration-time
  statement optional String // =statement
  requestId optional String // =request-id
  resources optional [ String ] // =resources as URIs
}

Adjusting the format to exclude optional fields, below is the message format with only required fields:

{cacao.p.domain} wants you to sign in with your Ethereum account:
{cacao.p.iss[address]}

URI: {cacao.p.aud}
Version: {cacao.p.version}
Chain ID: {cacao.p.iss[chainId.reference]}
Nonce: {cacao.p.nonce}
Issued At: {cacao.p.iat}

The following is an example of a EIP-4361 message using the previous message format (a modification of the example provided by the EIP-4361 specification) that could be signed by the owner of 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 and included the CACAO as the signature:

example.com wants you to sign in with your Ethereum account:
0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2

URI: https://example.com/login
Version: 1
Chain ID: 1
Nonce: 32891756
Issued At: 2021-09-30T16:25:24Z

Piecing it all together to authenticate with the "SIWx" grant type, the full end-to-end flow can be accomplished with the example code below:

const w3 = require('web3');

const apiBaseURL = 'https://api.relayer.tech';

// Construct a CACAO object and return a serialized Base64-encoded string
function createEncodedCacao(aud, iat, address, nonce, domain, signature) {
    const cacao = {
        "h": {
            "t": "eip4361"
        },
        // These fields are used to create `preparedMessage` below
        "p": {
            "aud": aud, // URI
            "iat": iat, // Issued At
            "iss": `did:pkh:eip155:1:${address}`, // Issuer
            "nonce": nonce,
            "domain": domain, // Domain
            "version": "1"
        },
        "s": {
            "s": signature,
            "t": "eip191"
        }
    }
    const serializedCacao = JSON.stringify(cacao)
    // Encode the string as Base64
    return Buffer.from(serializedCacao).toString('base64')
}

(async () => {
    // Client ID shared by Relayer
    const clientId = "<CLIENT ID>";
    // Address of the public/private key pair for message signing and authentication
    const address = "<SIGNING ADDRESS>";
    const privateKey = "<PRIVATE KEY>";
    const aud = "https://example.com";
    const iat = (new Date()).toISOString();
    const domain = "example.com";

    // Request a new unique nonce for signing
    let resp = await fetch(`${apiBaseURL}/v1/auth/nonce`)
    const nonce = await resp.text()

    // Prepare a message for signing using the data fields in the CACAO. 
    // The payload (`p`) of the CACAO represents this message and is used to prepare an identical 
    // one server-side to verify the signature
    //
    // EIP-4361 message format:
    // {cacao.p.domain} wants you to sign in with your Ethereum account:
    // {cacao.p.iss[address]}
    //
    // URI: {cacao.p.aud}
    // Version: {cacao.p.version}
    // Chain ID: {cacao.p.iss[chainId.reference]}
    // Nonce: {cacao.p.nonce}
    // Issued At: {cacao.p.iat}
    const preparedMessage = `${domain} wants you to sign in with your Ethereum account:
${address}

URI: ${aud}
Version: 1
Chain ID: 1
Nonce: ${nonce}
Issued At: ${iat}`;

    // Sign the formatted message using the private key associated with the address 
    // used in the `iss` field of the CACAO.
    // `preparedMessage` is wrapped as `"\x19Ethereum Signed Message:\n" + preparedMessage.length + preparedMessage`
    // as specified by EIP-191 (this is why "eip191" is used as the value for `cacao.s.t`).
    const signedData = w3.eth.accounts.sign(preparedMessage, privateKey);
    b64Cacao = createEncodedCacao(aud, iat, address, nonce, domain, signedData.signature);

    // Include `x-www-form-urlencoded` parameters for `grant_type` and `cacao` in the request.
    // "siwx" is the grant type used for authenticating on-chain accounts with Relayer.
    const params = new URLSearchParams();
    params.append('grant_type', 'siwx');
    params.append('cacao', b64Cacao);
    // Request an access token using the serialized CACAO
    resp = await fetch(`${apiBaseURL}/v1/auth/token`, {
        method: 'post',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Authorization': `Basic ${Buffer.from(`${clientId}:`).toString('base64')}`
        },
        body: params
    });
    const data = await resp.json();
    console.log(data);
})();

Last updated