POST/v1/chat/completions
Create a chat completion#
An OpenAI-compatible chat completion answered from the church's own teaching, so tools that speak that format can point at Folio. The last user message is the question; model is accepted and ignored and the response reports folio.
Pass the returned id's conversation as conversation_id to continue a thread. The request waits up to 55 seconds for the answer and answers 504 if it is slower. Streaming is not supported. usage is always zero. Errors use the Folio error envelope, not OpenAI's.
Auth. A church API key. Needs the ask:create scope, or a wildcard that includes it (machine:*, * on a partner key). A partner key can call it for a customer church by sending X-Folio-Church.
Plan. Needs the API and Ask features. A new conversation counts against the Ask allowance (402 quota_exceeded). Sandbox churches stop at their test AI budget.
Limits. Responses carry RateLimit-Limit and RateLimit-Remaining; a 429 carries Retry-After.
- Auth
- Church API key
- Scope
ask:create- Plan
- Needs the API and Ask features. A new conversation counts against the Ask allowance (402
quota_exceeded). Sandbox churches stop at their test AI budget. - Operation id
createChatCompletion
Parameters
| Name | In | Description |
|---|---|---|
Idempotency-Key | header | Makes a retry safe. The same key with the same body replays the first response for 24 hours; the same key with a different body returns 422; a duplicate that is still running returns 409 with Retry-After. Responses that carry a one-time secret are not replayed. (string, e.g. sunday-2026-11-01-upload) |
X-Folio-Church | header | Partner keys only: run this call as one of your customer churches (its org_ id or slug). The church must be one of yours, the key must be allowed to act for it, and plan checks run against that church. (string, e.g. org_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012) |
Request body
| Field | Type | Description |
|---|---|---|
conversation_id | string | Continue this conversation. |
messages | object[] | The messages. |
model | string | Accepted for compatibility and ignored. |
user | string | An end-user identifier, for your own records. |
{
"messages": [
{
"role": "user",
"content": "What did Sunday say about forgiveness?"
}
]
}Responses
200 Success. Create a chat completion.
{
"status": true,
"message": "ok",
"data": {
"id": "chatcmpl-conv_0192f7a8-3b1c-7d2e-9a40-5c6d7e8f9012",
"object": "chat.completion",
"created": 1793541609,
"model": "folio",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Forgiveness is a decision to release a debt, as God released ours. [1]"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 0
}
}
}400 The request could not be read.
{
"status": false,
"message": "the page cursor is not valid",
"error": {
"code": "invalid_argument",
"status": 400,
"request_id": "req_b337770ecebe03b03a88a8998b59263d"
}
}401 The key or session is missing, invalid or expired.
{
"status": false,
"message": "That API key is not valid or has expired.",
"error": {
"code": "unauthenticated",
"status": 401,
"request_id": "req_b337770ecebe03b03a88a8998b59263d"
}
}402 The Ask allowance or the AI budget is used up.
{
"status": false,
"message": "This church has used its Ask allowance for this month.",
"error": {
"code": "quota_exceeded",
"status": 402,
"request_id": "req_b337770ecebe03b03a88a8998b59263d"
}
}403 The credential lacks the scope, the church is suspended, the feature is not in the plan, or the address is not allowed.
{
"status": false,
"message": "That API key does not have the required scope.",
"error": {
"code": "permission_denied",
"status": 403,
"request_id": "req_b337770ecebe03b03a88a8998b59263d"
}
}404 The resource is not in this church.
{
"status": false,
"message": "That item is not in this church.",
"error": {
"code": "not_found",
"status": 404,
"request_id": "req_b337770ecebe03b03a88a8998b59263d"
}
}409 Conflict, including a duplicate Idempotency-Key still being processed.
{
"status": false,
"message": "A request with this Idempotency-Key is still running.",
"error": {
"code": "conflict",
"status": 409,
"request_id": "req_b337770ecebe03b03a88a8998b59263d"
}
}422 A field failed validation, or an Idempotency-Key was reused with a different body.
{
"status": false,
"message": "A field is not valid.",
"error": {
"code": "validation",
"status": 422,
"request_id": "req_b337770ecebe03b03a88a8998b59263d"
}
}429 Rate limited. Wait Retry-After seconds.
{
"status": false,
"message": "Too many requests. Wait before trying again.",
"error": {
"code": "rate_limited",
"status": 429,
"request_id": "req_b337770ecebe03b03a88a8998b59263d"
}
}500 Something went wrong. Quote error.request_id.
{
"status": false,
"message": "Something went wrong. Quote the request id to support.",
"error": {
"code": "internal",
"status": 500,
"request_id": "req_b337770ecebe03b03a88a8998b59263d"
}
}504 The answer took longer than 55 seconds. Read the conversation later.
{
"status": false,
"message": "The answer is taking too long.",
"error": {
"code": "unavailable",
"status": 504,
"request_id": "req_b337770ecebe03b03a88a8998b59263d"
}
}Code samples
curl -X POST "$FOLIO_API_URL/v1/chat/completions" \
-H "Authorization: Bearer $FOLIO_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: completion-1" \
-d '{
"messages": [
{
"role": "user",
"content": "What did Sunday say about forgiveness?"
}
]
}'