Errors and failures
Error responses, failure reasons, and how calls end.
Two different things can go wrong. A request can be refused, which returns an error at once. Or an action can run and fail, which ends it with a failure reason.
Error responses
Every response outside 2xx has the same body: an error object with a
code, a message for people, and, for invalid_request, the field that
failed.
| Status | Code | Meaning |
|---|---|---|
400 | invalid_request | The body or query failed validation. field names the first failing value. |
401 | unauthorized | The API key is missing, unknown, or revoked. |
403 | forbidden | The key lacks the scope this request or tool needs. |
404 | not_found | No such action or call for this key, or an unknown path. |
409 | idempotency_conflict | The Idempotency-Key was used with a different body. |
409 | action_not_waiting | An answer arrived when the action was not waiting_for_answer. |
409 | action_ended | A cancel arrived after the action ended. |
429 | rate_limited | Over the request rate or the running-action limit. Wait for the Retry-After header, in seconds. |
500 | internal_error | A Vene fault. Retry with the same Idempotency-Key. |
Validation errors
Vene reports the first failing value. field is its dotted path, with array
positions in brackets. Paths in an action's input start at input.
{
"error": {
"code": "invalid_request",
"message": "Expected a two-letter state code",
"field": "input.pharmacy.address.state"
}
}A missing value says Required. A field the schema does not define is refused
too, and field names that field:
{
"error": {
"code": "invalid_request",
"message": "Unrecognized key: \"pharmacy_phone\"",
"field": "input.pharmacy_phone"
}
}Answers name their position in the request, such as
answers[0].answer.value.
Failure reasons
An action that runs but cannot get a definite answer ends failed. Its
result.failure_reason says why, and result.next_step says what you could
do, when there is something.
| Reason | Meaning |
|---|---|
patient_authorization_required | The place acts only once the patient herself authorizes, such as by verbal consent, a call from her, or a signed release on file. next_step names the place, its number, and what it needs. Get that authorization, then send a new action. |
place_would_not_help | The place would not discuss it with Vene, including a place that will not deal with an AI. |
place_unreachable | The place was closed, never answered, or Vene found no working number. |
fee_over_max | The office's fee to cancel or move the appointment was over the request's max_fee, so Vene changed nothing. The result names the fee. |
declined_by_you | You declined something the action needed, such as answering unavailable to a question. |
internal_error | A Vene fault. next_step says to send the request again. |
A failure is not an error response. The action is readable as usual, with its calls and transcripts.
What succeeded means
succeeded means the place gave a definite answer, even when the answer is
bad news. A pharmacy with no record of a prescription returns succeeded with
fill_status: "not_found". A refused transfer returns succeeded with
transfer_status: "refused" and a refusal_reason.
How calls end
Each call in trail records how it ended. A call that ends without an answer
does not end the action. Vene decides what to do next, such as calling back
later.
ended_reason | Meaning |
|---|---|
completed | The call ran to its end. |
voicemail | It reached voicemail. |
no_answer | Nobody picked up. |
busy | The line was busy. |
they_hung_up | The place hung up. |
queue_callback | The place's phone queue took Vene's number to call back. The action waits as waiting_for_callback. |
long_hold | Vene hung up after about ten minutes on hold without reaching a person. The action tries again at a better hour. |
null | The call has not ended yet. |