Skip to main content

When the Practor API refuses a request, the body is sent as application/problem+json:

{
  "type": "https://developers.practor.app/guides/errors#validation-failed",
  "title": "Some fields are missing or wrong",
  "status": 422,
  "detail": "Fix the fields listed in errors and send it again.",
  "code": "validation_failed",
  "requestId": "x9k2m4p7q1w8e3r6t5y0u2i4",
  "errors": [
    { "field": "lastName", "code": "required", "message": "Send lastName." },
    { "field": "birthDate", "code": "invalid", "message": "birthDate must be a real date, written YYYY-MM-DD" }
  ]
}

Branch on code, which stays the same from release to release. detail is a sentence saying what went wrong. When fields failed their checks, errors lists every one Practor found, each with the field it's about, like birthDate or procedures.1.code. A field's code is required when you left it out and invalid when its value is wrong.

In the API reference, each request's page lists the statuses Practor can answer it with.

Every answer has an X-Request-Id header, refusals included, and a refusal repeats it as requestId. Keep it in your logs. The practice sees the same id on that request in its audit log, and it's the number to quote if you contact us.

Fix a refused key or address

StatusMessageWhat to do
401Send an integration key as "Authorization: Bearer <key>".Add the header
401The integration key is not valid.Check you copied the whole key. If you did, ask the practice to look the request up in its audit log
403The Integrations add-on is not active for this practice.Ask the practice to switch integrations on
403This integration client does not have Read on Invoices. A practice owner can add it under Permissions.Ask the practice to tick that permission. The permission and the records named vary

Practor gives the same answer for a key it doesn't know, one that was revoked or has expired, a client the practice suspended, and a call from an address the client isn't allowed to use. That way nobody holding an old key can learn which it is. The practice's audit log shows the reason against the request id.

Fix a refused request

StatusWhat it means
400The body isn't JSON
400A search parameter is missing or isn't in the form the search takes. errors names the parameter, like patientId, and the message shows the form to use
400The cursor isn't one Practor sent. Send nextCursor exactly as it came, with the same filters
404The record doesn't exist at this practice. A record at another practice answers the same way
405The address doesn't take that method. A PUT to /api/v1/patients, for example, is refused with an Allow header naming POST
409The record clashes with one that exists, such as a second patient with your patient number. The message names the one that's there
413The body is over 256 KB
415Send the body as application/json.
422The body is valid JSON but Practor can't accept it: a missing field, an unknown code, a plan that doesn't exist. errors says where
500Something went wrong on our side. Quote the requestId if you contact us

A 400, 404, 405 or 422, or a 409 about a clashing record, fails the same way if you send it again unchanged. Fix what the message says first.

Practor checks the key and the client's permission before the method, so a PUT to /api/v1/patients with a revoked key gets the 401, not the 405.

Retry safely

Retry a 429, a 500 or a timeout. A retried POST keeps its Idempotency-Key, as Send patients and visits to Practor from your own system explains.

StatusMessageWhat to do
400Send an Idempotency-Key header (up to 255 characters) with every create, so a retry cannot create the record twice.Add the header to every POST
409A request with this Idempotency-Key is still being processed. Retry shortly.Wait a few seconds, then retry
422This Idempotency-Key was already used with a different request body.Use a new key for each new record

Practor remembers a key for 24 hours.

Stay inside the limits

LimitWhat happens past it
600 requests a minute, per integration clientA 429 that reads "Too many requests for this integration client. Slow down and retry.", for a minute
30 visits billed a minute, per practice, across all its clientsA 429 that reads "Too many encounters billed for this practice in the last minute. Slow down and retry." Billing is refused the same way if Practor can't count, so a 429 here is always safe to retry
30 claims submitted, resubmitted or reversed a minute, per practiceA 429 that reads "Too many claims sent for this practice in the last minute. Slow down and retry."
30 checks of a patient's cover a minute, per practice, counting the practice's ownA 429 that reads "Too many insurance checks for this practice in the last minute. Slow down and retry."
30 requests from one address refused for their key, their client or their address, in 10 minutesFurther refused requests from that address get a 429 that reads "Too many refused requests from this address. Try again later.", for 10 minutes. A working key from that address carries on
50 results a page, for invoices, a patient's visits, plans, code systems and their codes, unless you set limit up to 100While hasMore is true, send nextCursor back as cursor for the next page

Once your key and permission are accepted, the answer carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. On a billing or claim request they count the practice's limit for those. A 429 adds Retry-After, in seconds. Wait that long before the next request.

If one of the practice's keys is refused more than 20 times in 10 minutes, the practice gets a notification naming the key, once a day at most.

Was this helpful?