Status Codes and Limits
Map each status code and error code from the API to its cause, and plan retries around the rate limits.
Status Codes
| Status | Error code | Returned by | Meaning |
|---|---|---|---|
200 | — | All four routes | The action succeeded. |
400 | invalid_request | Ping, Wake-on-LAN | The body failed validation, and issues lists each problem. |
400 | invalid_json | Any path | The body isn't valid JSON. |
401 | authentication_required | All four routes | The token is missing, malformed, unknown, or expired. |
403 | scope_required | All four routes | The token lacks the route's scope. |
404 | not_found | Unknown paths | No route matches the method and path. |
413 | payload_too_large | Any path | The JSON body is larger than 64 KB. |
415 | unsupported_encoding | Any path | The body uses a character set other than UTF-8, or a compression pfSense Actions can't read. |
429 | rate_limited | All four routes, and any path under /api/v1 | The client reached a rate limit. |
500 | internal_error | All four routes | The controller hit an unexpected error. |
502 | pfsense_unavailable | All four routes | pfSense Actions couldn't sign in to pfSense over SSH. |
502 | command_failed | All four routes | The pfSense command failed, or the system information route got unexpected output. |
503 | connection_not_configured | All four routes | No pfSense connection is saved yet, or its credential was removed. |
503 | target_unreachable | Ping | Every ping attempt finished without meeting the selected reachability condition. |
The console's own routes, including the notification routes, answer with codes of their own, such as session_required for a request with a token, as listed in Notifications.
Order of Checks
- The JSON body is parsed, so malformed JSON gets
400, an oversized body gets413, and a body pfSense Actions can't decode gets415. - The rate limits apply, so a client over a limit gets
429before anything else is checked. - The token is checked for
401, then its scope for403. - The body is validated for
400. - A route without a saved pfSense connection, or without its password or private key, answers
503. - pfSense Actions signs in over SSH and runs the command, which ends in
200,502, or503.
Rate Limits
- The four action routes share one limit of 3 requests per 10 seconds for each client IP address, whichever path a request uses.
- Every path under
/api/v1, including the console's, also counts toward a limit of 120 requests per minute for each address. - Requests rejected with
401or403still count, and so do unknown paths under/api/v1, which end in404. - Responses carry
RateLimit-Policy,RateLimit-Limit,RateLimit-Remaining, andRateLimit-Resetheaders. A429also carriesRetry-Afterin seconds. - Behind a reverse proxy, the client address comes from
X-Forwarded-For, as described in HTTPS Reverse Proxy.
The console's sign-in has its own limit on failed attempts, listed in the Security Model.
Retry Guidance
429— Wait for the number of seconds inRetry-Afterbefore sending again.500or502— Retrying the connectivity, system information, or ping route is safe, because they don't change anything. Retrying Wake-on-LAN sends another wake packet.503withtarget_unreachable— The device didn't meet the selected reachability condition, so retry later, raisecount, or turn off strict mode when partial replies are enough.503withconnection_not_configured— Save the pfSense connection in the console first, or enter its password or private key again whenerror.messageasks for it.400,401,403,404,413, or415— The same request keeps failing until something about it changes.
What Responses Never Contain
- SSH output, the command that ran, or SSH error details.
- Credentials, token values, or any token hash.
- The firewall's hostname or configuration.