expiresAfter is an optional field on supported Hyperliquid exchange actions. It is a timestamp in milliseconds. After that timestamp, the action is rejected. It is a request-validity deadline, not an order-cancellation instruction.
Primary sources: Exchange endpoint and Rate limits and user limits.
What expiresAfter controls
| Item | Behavior |
|---|---|
| Field type | Number: timestamp in milliseconds |
| Scope | Supported exchange actions |
| Effect after deadline | The action is rejected |
| Unsupported actions | User-signed actions such as Core USDC transfer do not support expiresAfter |
| Stale-action cost | Actions consume 5x the usual address-based rate limit when canceled due to a stale expiresAfter field |
Rate-limit cost of a stale action
The 5x penalty is address-based. Hyperliquid's address-based limits apply per user, with sub-accounts treated as separate users.
According to the docs:
- The rate-limiting logic allows 1 request per 1 USDC traded cumulatively since address inception.
- Each address starts with an initial buffer of 10,000 requests.
- When rate limited, an address is allowed one request every 10 seconds.
- Cancels have a cumulative limit of
min(limit + 100000, limit * 2), wherelimitis the default limit for other actions.
expiresAfter therefore uses address action capacity faster than a normal action. This matters for bots that may resend signed actions after a network delay, restart, or stale local clock.
For the broader IP and address limits, see Hyperliquid API Rate Limits & User Limits (2026).
expiresAfter is not an order-cancel field
Do not use expiresAfter as a way to cancel resting orders. Cancellation is a separate exchange action.
The exchange endpoint documents separate actions for:
Like what you're reading? Try it yourself โ this link supports ChartedTrader at no cost to you.
Create a Hyperliquid account โcancel: cancel one or more orders by order ID.cancelByCloid: cancel one or more orders by client order ID.scheduleCancel: schedule a cancel-all operation at a future time.
scheduleCancel is a dead man's switch: it schedules a future cancel-all operation. If no time is included, it removes the scheduled cancel operation. The scheduled time must be at least 5 seconds after the current time. Once triggered, all open orders are canceled and a trigger count is incremented; the maximum is 10 triggers per day, reset at 00:00 UTC.
If you are debugging rejected or unexpected exchange responses, also see Hyperliquid API Error Responses: Troubleshooting Guide (2026).
Example request shape
The following is a reference shape based on the documented order request body. It is not a live response or tested transaction.
{
"action": {
"type": "order",
"orders": [
{
"a": 0,
"b": true,
"p": "1891.4",
"s": "0.02",
"r": false,
"t": {
"limit": {
"tif": "Gtc"
}
}
}
],
"grouping": "na"
},
"nonce": 1762857600000,
"signature": {
"r": "0x...",
"s": "0x...",
"v": 27
},
"expiresAfter": 1762857660000
}
In this example, the action is valid only until 1762857660000 milliseconds. If the action is no longer valid after that timestamp, it is rejected. The docs recommend using the current timestamp in milliseconds for nonce.
Practical checks
- Use a millisecond timestamp for
expiresAfter. - Set the deadline long enough to absorb expected network and signing latency, but short enough that a delayed action cannot be accepted unintentionally.
- Do not resend an expired signed action expecting it to succeed.
- Monitor address-based rate-limit usage, because stale actions consume 5x the usual address-based rate limit.
- Use cancel actions or
scheduleCancelfor order cancellation, notexpiresAfter.
CTA
The Hyperliquid referral link below is a referral link; if you sign up through it, I may earn a commission.
Create a Hyperliquid accountContinue with Hyperliquid
Browse the Hyperliquid guide hub for the complete user journey.