> ## Documentation Index
> Fetch the complete documentation index at: https://aftercaredocs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# POST /ask — Ask a Question About Your Recovery Document

> Ask a natural-language question about your discharge document and receive a grounded answer with source line citations and a StructuredAiError on failure.

Send a natural-language question along with a `documentId` and AfterCare's AI returns an answer drawn directly from your discharge paperwork, together with the exact line numbers in the document where the answer was found. Every response is grounded in the document you uploaded — the API never invents information.

## Endpoint

```http theme={null}
POST /ask
```

## Request body

<ParamField body="question" type="string" required>
  The question you want to ask about your document. Must be between 1 and 1,000 characters after trimming whitespace.
</ParamField>

<ParamField body="documentId" type="string (UUID)" required>
  The UUID of the document to query. The document must belong to the authenticated user.
</ParamField>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.aftercare.app/ask \
    -H "Authorization: Bearer <your_access_token>" \
    -H "Content-Type: application/json" \
    -d '{
      "question": "When should I take metformin?",
      "documentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
    }'
  ```

  ```typescript TypeScript theme={null}
  const response = await fetch("https://api.aftercare.app/ask", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${accessToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      question: "When should I take metformin?",
      documentId: "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    }),
  });

  const data = await response.json();
  console.log(data.answer);
  ```
</CodeGroup>

## Response — 200 OK

The API returns a JSON object with the answer, a confidence score, and the source location within the document.

<ResponseField name="answer" type="string">
  The answer to your question, phrased in plain language and derived from the document text.
</ResponseField>

<ResponseField name="confidence" type="number">
  An integer between 0 and 100 expressing how confident the AI is in the answer, based on the clarity and completeness of the source text.
</ResponseField>

<ResponseField name="source" type="object">
  The location in the document from which the answer was derived.

  <Expandable title="source fields">
    <ResponseField name="source.documentId" type="string (UUID)">
      The UUID of the document that was queried. Matches the `documentId` you sent in the request.
    </ResponseField>

    <ResponseField name="source.sourceLines" type="number[]">
      The 1-based line numbers in the original document that contain the evidence for the answer. May be an empty array if the AI could not pin the answer to specific lines.
    </ResponseField>
  </Expandable>
</ResponseField>

```json Example response theme={null}
{
  "answer": "Take metformin with your evening meal.",
  "confidence": 92,
  "source": {
    "documentId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "sourceLines": [14, 15]
  }
}
```

<Warning>
  If `sourceLines` is empty, the answer was **not** derived from a specific passage in your document. The AI will say so explicitly in the `answer` text. Treat any answer with an empty `sourceLines` as unverified and confirm it with your care team before acting on it.
</Warning>

## Error responses

AfterCare uses a `StructuredAiError` shape for all AI-related failures. Every error response includes a `code`, a human-readable `message`, and a `retryable` flag.

```json StructuredAiError shape theme={null}
{
  "code": "AI_PROVIDER_OUTAGE",
  "message": "The AI provider is temporarily unavailable. Please try again shortly.",
  "retryable": true
}
```

### 400 Bad Request

Returned when `question` is missing or empty, or when `documentId` is not a valid UUID.

### 404 Not Found

Returned when the document does not exist or does not belong to the authenticated user.

### 422 Unprocessable Entity

Returned when the AI pipeline completes but the output fails validation — for example, when the model returns a malformed or unsafe response. The `retryable` field will be `false`. Do not retry a 422 automatically; inspect the `code` and surface the `message` to the user.

```json 422 example theme={null}
{
  "code": "AI_VALIDATION_FAILED",
  "message": "The AI response did not pass safety validation.",
  "retryable": false
}
```

### 503 Service Unavailable

Returned when the AI provider is unreachable, suffering an outage, or has not been configured in this environment.

```json 503 example theme={null}
{
  "code": "AI_PROVIDER_OUTAGE",
  "message": "The AI provider is temporarily unavailable.",
  "retryable": true
}
```

<Note>
  When you receive a 503 with `"retryable": true`, wait a short interval (start with two to five seconds) and retry the request. A 503 with `"retryable": false` indicates a configuration problem that cannot be resolved by retrying.
</Note>

## Error code reference

| Code | Retryable | Meaning |
| - | - | - |
| `AI_PROVIDER_CONFIG_MISSING` | `false` | The AI provider credentials are absent from the server configuration. |
| `AI_PROVIDER_OUTAGE` | `true` | The AI provider is experiencing a temporary outage. |
| `AI_PROVIDER_UNAVAILABLE` | `true` | The AI provider cannot be reached right now. |
| `AI_VALIDATION_FAILED` | `false` | The AI response failed internal safety or schema validation. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.