Troubleshooting
Common API errors and debugging
Use this runbook to diagnose and resolve common HTTP API errors returned by pycli when creating, listing, viewing, or canceling orders.
This runbook covers HTTP 4xx and 5xx error responses from the pycli API endpoints (POST /orders, GET /orders, GET /orders/{order_id}, DELETE /orders/{order_id}), how to interpret error shapes, and steps to recover from common failure states.
This runbook does not cover:
- CLI (
pycli deploy,pycli config set) errors or exit codes - Network-layer issues (DNS, TLS, firewall)
- Server-side infrastructure failures beyond what the API surface exposes
- Authentication and authorization configuration (covered separately)
Before working through this runbook, confirm you have the following:
- curl or an equivalent HTTP client installed and accessible on your
PATH - The pycli API base URL (
https://api.example.com) confirmed reachable from your environment - A valid
Content-Type: application/jsonheader available for any POST requests you need to replay - Basic familiarity with reading JSON response bodies
- Any
order_idvalues relevant to the request you are debugging
Work through these steps in order, stopping when you identify and resolve your error.
1. Reproduce the error and capture the full response
Run the failing request with -i so curl prints both headers and body. For example, to replay a failed order creation:
curl -i -X POST https://api.example.com/orders \
-H 'Content-Type: application/json' \
-d '{"amount": 1500, "currency": "USD"}'
For a failing fetch:
curl -i https://api.example.com/orders/42
Success looks like an HTTP 200 or 201 status line at the top of the response. If you see a 4xx or 5xx status, continue to the next step.
2. Check for HTTP 422 — Invalid request body (POST /orders only)
A 422 Unprocessable Entity means the JSON body you sent failed schema validation. The POST /orders endpoint expects a body matching the CreateOrderBody shape:
{
"amount": 1500,
"currency": "USD"
}
Common causes:
- Missing
amountorcurrencyfield amountsent as a string instead of a number- Malformed JSON (unquoted keys, trailing commas)
- Wrong or missing
Content-Type: application/jsonheader
Verify your request body is valid JSON before resending:
echo '{"amount": 1500, "currency": "USD"}' | python3 -m json.tool
If the command prints the formatted object without errors, the JSON is valid. Correct any fields flagged in the API error response body and retry step 1.
3. Check for HTTP 404 — Order not found (GET or DELETE /orders/{order_id})
A 404 Not Found on GET /orders/42 or DELETE /orders/42 means the order ID does not exist or has already been deleted.
- Confirm the
order_idvalue by listing orders and scanning the results:
curl 'https://api.example.com/orders?limit=10'
- If you are trying to cancel an order, it may have already been canceled. A previous
DELETEis non-reversible; confirm the order is absent from the list before escalating. - If the ID came from a previous
POST /ordersresponse, check that you copied it without truncation or extra whitespace.
4. Check for HTTP 400 — Bad query parameters (GET /orders)
A 400 Bad Request on the list endpoint usually means a query parameter has an unexpected value. The status filter accepts specific values (for example, paid); passing an unrecognized status string may trigger this error.
Retry with known-good parameters to isolate the problem:
curl 'https://api.example.com/orders?limit=10'
If this succeeds, reintroduce your original query parameters one at a time to identify the offending value.
5. Check for HTTP 5xx — Server-side errors
A 500 Internal Server Error or other 5xx response indicates a problem on the server, not in your request. Steps you can take:
- Wait 30–60 seconds and retry the identical request. Transient errors often resolve on retry.
- Simplify your request to the minimal valid payload to rule out an edge case in your data.
- Check whether the issue affects all endpoints or only one (e.g., POST works but GET /orders/{id} consistently returns 500).
If retries do not resolve the error within a few minutes, proceed to the Escalation section.
6. Verify connectivity if all requests fail
If every endpoint returns an error or times out, confirm basic reachability:
curl -i https://api.example.com/orders?limit=1
A connection timeout or 000 curl exit code (rather than an HTTP status code) indicates a network or infrastructure issue outside the API itself, which is out of scope for this runbook.
After applying a fix, confirm resolution with the following checks:
- Order creation: A successful
POST /ordersreturns HTTP201(or200) with a JSON body containing the new order's ID and details. No error fields should be present. - Order listing:
GET /orders?limit=10returns HTTP200with a JSON array. The order you just created (if applicable) should appear in the list. - Single order fetch:
GET /orders/{order_id}with the correct ID returns HTTP200and the expected order object. - Order cancellation:
DELETE /orders/{order_id}returns a200or204success status. A subsequentGET /orders/{order_id}should return404, confirming the order no longer exists.
If all targeted endpoints return 2xx responses with well-formed JSON bodies, the issue is resolved.
Most read operations (GET /orders, GET /orders/{order_id}) are safe to retry without side effects.
For write operations:
-
Accidentally created an order (
POST /orders): Cancel it immediately using theorder_idreturned in the creation response:curl -X DELETE https://api.example.com/orders/{order_id}Confirm cancellation by verifying the subsequent
GET /orders/{order_id}returns404. -
Accidentally canceled an order (
DELETE /orders/{order_id}): Deletion is permanent based on the current API surface. There is no restore endpoint. If the order must be recreated, issue a newPOST /orderswith the original parameters and treat it as a new order.
If you have completed all steps above and the error persists, escalate with the following information to reduce back-and-forth:
- The full curl command you ran (redact any sensitive values)
- The complete HTTP response including status line, headers, and body (captured with
-i) - The endpoint and method affected (e.g.,
POST /orders) - Whether the issue is consistent or intermittent — include how many retries you attempted and over what time window
- Any
order_idvalues relevant to the failing request - The timestamp(s) of the failing requests in UTC