Apply Referral
Attribute a referral code to your wallet. The wallet is derived from the EIP-712 signature — no separate wallet address field is required or accepted.
Unlike most trade endpoints, applyReferral does not use a top-level { v, r, s } signature or nonce. The EIP-712 signature is passed as a 0x-prefixed hex string inside params.
Endpoint
POST https://papi.synthetix.io/v1/tradeRequest
Request Format
{
"params": {
"action": "applyReferral",
"referralCode": "FRIEND50",
"expiresAfter": 1704067500,
"signature": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12"
}
}Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
params | object | Yes | Request parameters wrapper |
params.action | string | Yes | Must be "applyReferral" |
params.referralCode | string | Yes | The referral code to apply (leading and trailing whitespace is trimmed) |
params.expiresAfter | integer | Yes | Signature expiry as a Unix timestamp in seconds; must be in the future and within 5 minutes of the current server time |
params.signature | string | Yes | 0x-prefixed hex encoding of the EIP-712 signature over the ApplyReferral typed data |
:::info Owner key required
applyReferral must be signed with the wallet owner key. Signing with a delegate key would attribute the referral to the delegate address, not the owner. There is no walletAddress field — the signing address IS the wallet being attributed.
:::
Response
Success Response
{
"status": "ok",
"response": {
"attributed": true
},
"request_id": "5ccf215d37e3ae6d"
}Response Fields
| Field | Type | Description |
|---|---|---|
attributed | boolean | true if a new referral row was created for this wallet. false if this was a silent no-op (self-referral, wallet already attributed, or wallet already has a subaccount). |
:::note Silent no-op behavior
A false response is not an error. The server returns 200 OK with attributed: false for self-referrals, wallets that already have an attribution, and wallets that already own a subaccount at the time of the request. Integrators should treat both true and false as success states.
:::
Authentication
EIP-712 Signature
applyReferral uses a dedicated EIP-712 primary type ApplyReferral. The signed payload contains referralCode and expiresAfter. The signer of the signature is the wallet receiving the attribution.
ApplyReferral Type Definition
const ApplyReferralTypes = {
ApplyReferral: [
{ name: "referralCode", type: "string" },
{ name: "expiresAfter", type: "uint256" }
]
}Example Typed Data for ApplyReferral
{
"types": {
"EIP712Domain": [
{ "name": "name", "type": "string" },
{ "name": "version", "type": "string" },
{ "name": "chainId", "type": "uint256" },
{ "name": "verifyingContract", "type": "address" }
],
"ApplyReferral": [
{ "name": "referralCode", "type": "string" },
{ "name": "expiresAfter", "type": "uint256" }
]
},
"primaryType": "ApplyReferral",
"domain": {
"name": "Synthetix",
"version": "1",
"chainId": 1,
"verifyingContract": "0x0000000000000000000000000000000000000000"
},
"message": {
"referralCode": "FRIEND50",
"expiresAfter": "1704067500"
}
}- Serialize the signed payload to
params.signatureas a single0x-prefixed hex string (standard Ethereum signature bytes), not as a top-level{ v, r, s }object expiresAfteris encoded as a decimal string in the EIP-712 message (matching theuint256type encoding)- The signed
referralCodemust exactly match (after trimming) the value sent inparams.referralCode expiresAftermust be a future Unix second timestamp and no more than 5 minutes ahead of current server time- There is no nonce field — replay protection relies on the short validity window and the uniqueness constraint on referee address in the referral store
- Use the
chainIdfor your target environment. See Environments for the domain configuration used on mainnet and testnet
For general EIP-712 background, see EIP-712 Signing.
Validation Rules
referralCodemust be a non-empty string (after trimming)expiresAftermust be a positive integer representing a future Unix timestamp in secondsexpiresAftermust be within 5 minutes of the current server timeparams.signaturemust be a valid EIP-712 signature over theApplyReferraltyped data, passed as a0x-prefixed hex string insideparams- No
noncefield is used; this action uses expiry-window replay protection only
Error Handling
| Error Code | Description | Retryable |
|---|---|---|
UNAUTHORIZED | EIP-712 signature validation failed | No |
VALIDATION_ERROR | Request validation failed | No |
MISSING_REQUIRED_FIELD | Required field is missing | No |
INVALID_FORMAT | Field format is invalid | No |
INVALID_VALUE | Invalid parameter value | No |
RATE_LIMIT_EXCEEDED | Too many requests in time window | Yes |
INSUFFICIENT_MARGIN | Not enough margin for trade | No |
ORDER_NOT_FOUND | Order does not exist | No |
OPERATION_TIMEOUT | Operation timed out | Yes |
| Error | Description |
|---|---|
referralCode is required | referralCode is missing or blank after trimming |
expiresAfter is required and must be a future unix-second timestamp | expiresAfter is missing, zero, or in the past |
signature is required | params.signature is missing or blank |
signature verification failed | Signature is invalid or expiresAfter exceeds the 5-minute validity window |
404 Not Found | Referral code does not exist |
Related
- Claim Referral — Claim accrued referral commissions
- Get Referral — View referral dashboard and earnings