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
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 theAuthorization
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
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 theAuthorization
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
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 theAuthorization
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
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. Iftrue
the user will be enrolled once created, iffalse
the user will not be enrolled. Defaults tofalse
. 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-2namespace
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
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-2namespace
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
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 isnull
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-2namespace
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
Authorization
Bearer <access token>
Request
Path
id
(string) requiredThe 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
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-2namespace
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
Content-Type
application/json
Authorization
Bearer <access token>
Request
Path
id
(string) requiredThe 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-2namespace
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
Content-Type
application/json
Authorization
Bearer <access token>
Request
Path
id
(string) requiredThe 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
Content-Type
application/json
Authorization
Bearer <access token>
Request
Path
id
(string) requiredThe 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
Content-Type
application/json
Authorization
Bearer <access token>
Request
Path
id
(string) requiredThe 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-2namespace
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
Authorization
Bearer <access token>
Request
Path
id
(string) requiredThe 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
Authorization
Bearer <access token>
Request
Path
id
(string) requiredThe 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
Authorization
Bearer <access token>
Request
Path
id
(string) requiredThe 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
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 ornull
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-2namespace
of the blockchain standard/ecosystem the account is on.caip2_reference
(string) required The CAIP-2reference
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-2namespace
of the blockchain standard/ecosystem the account is on.caip2_reference
(string) required The CAIP-2reference
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
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
Authorization
Bearer <access token>
Request
Path
id
(string) requiredThe 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 ornull
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-2namespace
of the blockchain standard/ecosystem the account is on.caip2_reference
(string) required The CAIP-2reference
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-2namespace
of the blockchain standard/ecosystem the account is on.caip2_reference
(string) required The CAIP-2reference
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
Authorization
Bearer <access token>
Request
Path
id
(string) requiredThe 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 ornull
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-2namespace
of the blockchain standard/ecosystem the account is on.caip2_reference
(string) required The CAIP-2reference
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-2namespace
of the blockchain standard/ecosystem the account is on.caip2_reference
(string) required The CAIP-2reference
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
Content-Type
application/json
Authorization
Bearer <access token>
Request
Path
id
(string) requiredThe 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 ornull
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-2namespace
of the blockchain standard/ecosystem the account is on.caip2_reference
(string) required The CAIP-2reference
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-2namespace
of the blockchain standard/ecosystem the account is on.caip2_reference
(string) required The CAIP-2reference
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.
(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