Skip to content

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/trade

Request

Request Format

{
  "params": {
    "action": "applyReferral",
    "referralCode": "FRIEND50",
    "expiresAfter": 1704067500,
    "signature": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef12"
  }
}

Request Parameters

ParameterTypeRequiredDescription
paramsobjectYesRequest parameters wrapper
params.actionstringYesMust be "applyReferral"
params.referralCodestringYesThe referral code to apply (leading and trailing whitespace is trimmed)
params.expiresAfterintegerYesSignature expiry as a Unix timestamp in seconds; must be in the future and within 5 minutes of the current server time
params.signaturestringYes0x-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

FieldTypeDescription
attributedbooleantrue 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"
  }
}
Important notes:
  • Serialize the signed payload to params.signature as a single 0x-prefixed hex string (standard Ethereum signature bytes), not as a top-level { v, r, s } object
  • expiresAfter is encoded as a decimal string in the EIP-712 message (matching the uint256 type encoding)
  • The signed referralCode must exactly match (after trimming) the value sent in params.referralCode
  • expiresAfter must 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 chainId for 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

  • referralCode must be a non-empty string (after trimming)
  • expiresAfter must be a positive integer representing a future Unix timestamp in seconds
  • expiresAfter must be within 5 minutes of the current server time
  • params.signature must be a valid EIP-712 signature over the ApplyReferral typed data, passed as a 0x-prefixed hex string inside params
  • No nonce field is used; this action uses expiry-window replay protection only

Error Handling

Error CodeDescriptionRetryable
UNAUTHORIZEDEIP-712 signature validation failedNo
VALIDATION_ERRORRequest validation failedNo
MISSING_REQUIRED_FIELDRequired field is missingNo
INVALID_FORMATField format is invalidNo
INVALID_VALUEInvalid parameter valueNo
RATE_LIMIT_EXCEEDEDToo many requests in time windowYes
INSUFFICIENT_MARGINNot enough margin for tradeNo
ORDER_NOT_FOUNDOrder does not existNo
OPERATION_TIMEOUTOperation timed outYes
ErrorDescription
referralCode is requiredreferralCode is missing or blank after trimming
expiresAfter is required and must be a future unix-second timestampexpiresAfter is missing, zero, or in the past
signature is requiredparams.signature is missing or blank
signature verification failedSignature is invalid or expiresAfter exceeds the 5-minute validity window
404 Not FoundReferral code does not exist

Related