API cURL Cookbook
Practical cURL snippets for local development and smoke checks.
Prerequisites
export API_URL="http://localhost:4000"
export EMAIL="developer@example.com"
Optional helper:
# macOS (optional)
brew install jq
1) Request OTP
curl -s -X POST "$API_URL/api/auth/request-otp" \
-H "Content-Type: application/json" \
-d '{"email":"'"$EMAIL"'","lang":"en"}'
2) Verify OTP and store token
Replace 12345678 with the real code from Mailpit/provider.
OTP_CODE="12345678"
TOKEN=$(curl -s -X POST "$API_URL/api/auth/verify-otp" \
-H "Content-Type: application/json" \
-d '{"email":"'"$EMAIL"'","code":"'"$OTP_CODE"'"}' | jq -r '.token')
echo "$TOKEN"
3) Create ticket (multipart + attachment)
curl -s -X POST "$API_URL/api/tickets" \
-H "Authorization: Bearer $TOKEN" \
-F "title=API cookbook test ticket" \
-F "description=Detailed reproduction details for smoke check." \
-F "category=other" \
-F "urgency_reporter=normal" \
-F "attachments=@./README.md"
4) List my tickets
curl -s "$API_URL/api/tickets" \
-H "Authorization: Bearer $TOKEN" | jq
5) Open ticket detail
TICKET_ID="<ticket-id>"
curl -s "$API_URL/api/tickets/$TICKET_ID" \
-H "Authorization: Bearer $TOKEN" | jq
6) Developer: move status to verified
curl -s -X PATCH "$API_URL/api/tickets/$TICKET_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"status":"verified"}' | jq
7) Add closure summary, then close ticket
curl -s -X POST "$API_URL/api/tickets/$TICKET_ID/comments" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"content":"Implemented fix and validated in QA.","type":"comment","is_internal":false,"is_closure_summary":true}' | jq
curl -s -X PATCH "$API_URL/api/tickets/$TICKET_ID" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"status":"closed"}' | jq
8) Check capabilities and outbox stats (developer)
curl -s "$API_URL/api/settings/capabilities" \
-H "Authorization: Bearer $TOKEN" | jq
curl -s "$API_URL/api/settings/events/outbox/stats" \
-H "Authorization: Bearer $TOKEN" | jq
9) Common failure checks
401 unauthorized: token missing/expired.403 forbidden: role or ownership restriction.400 closure_summary_required: closure summary comment required before close.400 domain_not_allowed: email domain not inallowed_domains.