Skip to content
FolioSign inStart your trial

API reference

Chat completions

An OpenAI-compatible endpoint answered from the church's own teaching.

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

Parameters
NameInDescription
Idempotency-KeyheaderMakes 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-ChurchheaderPartner 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

Request body fields
FieldTypeDescription
conversation_idstringContinue this conversation.
messagesobject[]The messages.
modelstringAccepted for compatibility and ignored.
userstringAn end-user identifier, for your own records.
Example request body
{
  "messages": [
    {
      "role": "user",
      "content": "What did Sunday say about forgiveness?"
    }
  ]
}

Responses

200 Success. Create a chat completion.
200 example
{
  "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.
400 example
{
  "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.
401 example
{
  "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.
402 example
{
  "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.
403 example
{
  "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.
404 example
{
  "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.
409 example
{
  "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.
422 example
{
  "status": false,
  "message": "A field is not valid.",
  "error": {
    "code": "validation",
    "status": 422,
    "request_id": "req_b337770ecebe03b03a88a8998b59263d"
  }
}
429 Rate limited. Wait Retry-After seconds.
429 example
{
  "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.
500 example
{
  "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.
504 example
{
  "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?"
    }
  ]
}'

Verified against API version 0.0.0-dev. Generated from the live OpenAPI document.