Sign Request API
HTTP Request
POST /v5/pay/agreement/sign
Create a sign request to initiate the agreement signing process. Returns a QR code and URL for the user to scan and complete authorization.
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchantId | string | Yes | Merchant ID |
| agreementType | string | Yes | Sign type: CYCLE (periodic deduction) / NON_CYCLE (non-periodic deduction) / SINGLE (single authorization) |
| sceneCode | string | Yes | Scene code - Supports 17 scenarios including TAXI, PARKING, SUBSCRIPTION, FOOD, ENTERTAINMENT, EDUCATION, etc. |
| productCode | string | Yes | Product code (assigned by platform) |
| externalAgreementNo | string | Yes | Merchant agreement number (unique) |
| notifyUrl | string | Yes | Sign result webhook URL |
| merchantUserId | string | No | Merchant-side user ID (optional, used for merchant internal user association. If not provided, agreement will only be bound to platform userId) |
| signValidTime | string | No | Sign validity period (ISO8601 format, must be at least 24 hours after current time) |
| singleLimit | object | No | Single transaction limit |
| singleLimit.amount | string | Conditional | Limit amount (required if singleLimit provided) |
| singleLimit.currency | string | Conditional | Currency code |
| singleLimit.currencyType | string | Conditional | FIAT or CRYPTO |
| singleLimit.chain | string | No | Chain network (for crypto, e.g., BSC, TRX, ARBI, LTC, SOL, ETH, TON, APTOS) |
| singleLimit.chainAddress | string | No | Chain address (required in dynamic chain settlement mode) |
| periodLimits | array | No | Period limit configuration list |
| periodLimits[].periodType | string | Conditional | DAY / WEEK / MONTH / YEAR |
| periodLimits[].amount | string | Conditional | Period limit amount |
| periodLimits[].currency | string | Conditional | Currency code |
| periodLimits[].currencyType | string | Conditional | FIAT or CRYPTO |
| periodLimits[].chain | string | No | Chain network (e.g., BSC, TRX, ARBI, LTC, SOL, ETH, TON, APTOS) |
| periodLimits[].chainAddress | string | No | Chain address (required in dynamic chain settlement mode) |
| returnUrl | string | No | Redirect URL after sign completion |
| signExpireMinutes | int | No | Sign link validity (minutes), default 30, max 1440 |
| extraParams | string | No | Extension parameters (JSON string, passed through) |
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| retCode | int | Response code |
| retMsg | string | Response message |
| result | object | Response data |
| result.signOrderId | string | Platform sign order number |
| result.signUrl | string | Sign page URL (for H5 redirect) |
| result.qrCode | string | Sign QR code content (for App scan) |
| result.qrCodeUrl | string | Sign QR code image URL |
| result.expireTime | string | Sign link expiration time |
Request Example
Basic Sign Request
POST /v5/pay/agreement/sign HTTP/1.1
Host: api.bybit.com
Content-Type: application/json
X-Request-Id: 550e8400-e29b-41d4-a716-446655440000
X-Timestamp: 1736233200000
X-Signature: {signature}
Authorization: Bearer {access_token}
{
"merchantId": "M123456789",
"agreementType": "CYCLE",
"merchantUserId": "merchant_user_123",
"sceneCode": "SUBSCRIPTION",
"externalAgreementNo": "MERCHANT_AGR_001",
"notifyUrl": "https://merchant.com/notify/sign"
}
Sign Request with Limits
POST /v5/pay/agreement/sign HTTP/1.1
Host: api.bybit.com
Content-Type: application/json
X-Request-Id: 550e8400-e29b-41d4-a716-446655440000
X-Timestamp: 1736233200000
X-Signature: {signature}
Authorization: Bearer {access_token}
{
"merchantId": "M123456789",
"agreementType": "CYCLE",
"merchantUserId": "merchant_user_123",
"sceneCode": "SUBSCRIPTION",
"productCode": "PROD_001",
"externalAgreementNo": "MERCHANT_AGR_002",
"signValidTime": "2027-12-31T23:59:59Z",
"singleLimit": {
"amount": "100000",
"currency": "USDT",
"currencyType": "CRYPTO",
"chain": "TRC20"
},
"periodLimits": [
{
"periodType": "DAY",
"amount": "500000",
"currency": "USDT",
"currencyType": "CRYPTO",
"chain": "TRC20"
},
{
"periodType": "MONTH",
"amount": "5000000",
"currency": "USDT",
"currencyType": "CRYPTO",
"chain": "TRC20"
}
],
"notifyUrl": "https://merchant.com/notify/sign",
"returnUrl": "https://merchant.com/return",
"signExpireMinutes": 60
}
Response Example
Success Response
{
"retCode": 20000,
"retMsg": "Success",
"result": {
"signOrderId": "AGR202601070001",
"signUrl": "https://pay.bybit.com/sign?token=xxx",
"qrCode": "https://pay.bybit.com/sign?token=xxx",
"qrCodeUrl": "https://pay.bybit.com/qr/AGR202601070001.png",
"expireTime": "2026-01-07T11:30:00Z"
}
}
Failure Response
{
"retCode": 40001,
"retMsg": "Parameter error: externalAgreementNo already exists",
"result": null
}
Sign Types
| Type | Description | Use Case |
|---|---|---|
CYCLE | Periodic deduction | Subscriptions, recurring payments |
NON_CYCLE | Non-periodic deduction | On-demand payments (e.g., ride-hailing, parking) |
SINGLE | Single authorization | One-time pre-authorization |
Notes
- User Identity Mapping:
merchantUserIdis optional and can be used to establish mapping between merchant's user system and Bybit platform. If not provided, agreement will only be bound to platform userId - Limit Configuration: If not provided, platform default limits apply
- Sign Expiration: Default 30 minutes, can be extended up to 24 hours
- Idempotency: Same
externalAgreementNoreturns existing sign request result