For IT departments
Ingestion API: your systems feed the assistant
Your systems (database, ERP, intranet, automation tool such as n8n or Make) push content themselves to the knowledge base of a QuickAsk assistant, and update or remove it when it changes. Each item of content is identified by an ID you choose.
Security: what you need to know
- You do the sending: QuickAsk never connects to your network and holds no credentials of yours.
- No firewall opening or installation is needed: a simple outbound HTTPS call is enough.
- A key is valid for a single assistant only. There is no account-wide key.
- The key is shown only once, when it is created. QuickAsk only keeps a fingerprint of it, like a password: nobody, including us, can read it back.
- The key can only add, update, remove and list the content it has sent. It cannot read the text of the knowledge base or the conversations.
- Content sent goes through the same checks as a file added by hand: real format verification, processing in an isolated environment, blocking of text that tries to give instructions to the assistant.
- The assistant’s owner can revoke a key at any time; they see when each key was last used and a log of recent activity (kept for 30 days, with no IP address or content).
Get started in 3 steps
- In QuickAsk, the assistant’s owner opens the assistant, “Knowledge” tab, “Automatic sending from your software” section, and clicks “Create a key”.
- They pass you the key (which starts with qak_) and the assistant ID shown next to it. Store the key in your secrets vault.
- Your system sends its content with the “Authorization: Bearer” header followed by the key, as in the examples below.
Endpoints
Base URL: https://www.quick-ask.app/api/v1
| PUT | /bots/{bot_id}/knowledge/{external_id} | Creates or updates the content identified by this ID. Sending exactly the same content again costs nothing and changes nothing. |
| DELETE | /bots/{bot_id}/knowledge/{external_id} | Removes this content from the assistant’s knowledge base. |
| GET | /bots/{bot_id}/knowledge?limit=1..500&cursor=… | Lists the content sent through the API (ID, title, URL, dates, size), page by page. |
The external ID is the one from your system (“product-123”, “faq:delivery”…): 1 to 128 characters, letters, digits and . _ - : ~ @, starting with a letter or a digit.
Sending content
| Field | Details |
|---|---|
| content | The text of the content (JSON). Required if no file is sent. |
| file | Or a file, as multipart/form-data: PDF, Word, Excel, PowerPoint, CSV, plain text or Markdown. |
| title | Optional. The title shown in the assistant’s knowledge (default: the file name or the ID). |
| format | Optional: “text” (default) or “markdown”, for splitting that follows the headings. |
| source_url | Optional. The original URL of the content, shown as its source. QuickAsk never visits it: an intranet address is fine. |
| updated_at | Optional. Date of the last update on your side (ISO 8601). When two items of content contradict each other, the assistant favours the most recent one. |
curl -X PUT "https://www.quick-ask.app/api/v1/bots/$BOT_ID/knowledge/faq-delivery" \
-H "Authorization: Bearer $QUICKASK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Delivery times",
"format": "markdown",
"content": "## Delivery\nOrders placed before 2 pm ship the same day.",
"source_url": "https://intranet.example.com/faq/delivery",
"updated_at": "2026-10-13T09:30:00Z"
}'curl -X PUT "https://www.quick-ask.app/api/v1/bots/$BOT_ID/knowledge/hr-handbook" \
-H "Authorization: Bearer $QUICKASK_API_KEY" \
-F "[email protected]" \
-F "title=Employee handbook" \
-F "updated_at=2026-09-01"Responses
created— 201: the content did not exist, it has been added.updated— 200: the content has changed; only the modified parts are reprocessed.unchanged— 200: content identical to the last one sent, nothing is reprocessed. You can therefore resend everything at each sync.
HTTP/1.1 201 Created
{
"external_id": "faq-delivery",
"status": "created", // "updated" or "unchanged" on the next calls
"title": "Delivery times",
"document_name": "[API] Delivery times",
"chunks": 1,
"indexed_bytes": 58, // 0 when nothing changed
"source_url": "https://intranet.example.com/faq/delivery",
"updated_at": "2026-10-13T09:30:00.000Z"
}Removing and listing
curl -X DELETE "https://www.quick-ask.app/api/v1/bots/$BOT_ID/knowledge/faq-delivery" \
-H "Authorization: Bearer $QUICKASK_API_KEY"curl "https://www.quick-ask.app/api/v1/bots/$BOT_ID/knowledge?limit=100" \
-H "Authorization: Bearer $QUICKASK_API_KEY"
# → { "items": [ { "external_id": "faq-delivery", "title": "...", "updated_at": "...",
# "indexed_at": "...", "size_bytes": 58, "chunks": 1, ... } ],
# "next_cursor": null } // pass ?cursor=<next_cursor> to get the next pageLimits
- Size: 2 MB of text at most per item of content, 4 MB per file.
- Accepted files: pdf, docx, xlsx, pptx, csv, txt, md. Images, audio, video and scanned PDFs (with no text) are not read by the API.
- Rate: 60 calls per minute per key.
- Volume of new or changed content per assistant per 24 h: 10 MB (Business), 25 MB (Pro), 50 MB (Agency and custom). Unchanged content does not count.
- The plan’s storage space applies, just as for a file added by hand.
- The API is available from the Business plan.
- Content sent through the API is not deducted from the plan’s requests.
Errors
An error returns an HTTP status code and a JSON body whose error field contains a code and a message. The code is stable: rely on it, not on the message. When retrying makes sense, the Retry-After header gives the delay in seconds.
HTTP/1.1 429 Too Many Requests
Retry-After: 60
{ "error": { "code": "rate_limited", "message": "Too many requests: at most 60 per minute per key." } }| HTTP status | Error code | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed request (invalid list parameter, unreadable body). |
| 400 | invalid_json | The body is not valid JSON. |
| 400 | invalid_external_id | Invalid external ID. |
| 400 | invalid_title | Title empty or too long (200 characters at most). |
| 400 | invalid_source_url | Invalid source URL (http or https only). |
| 400 | invalid_updated_at | Invalid date (ISO 8601 format expected). |
| 400 | invalid_format | The format must be “text” or “markdown”. |
| 400 | missing_content | Neither text nor file in the request. |
| 401 | missing_key | Key missing from the Authorization header. |
| 401 | invalid_key | Unknown key. |
| 401 | key_revoked | Key revoked: ask the assistant’s owner for a new one. |
| 403 | key_not_for_this_bot | This key belongs to another assistant. |
| 403 | plan_required | The account’s plan does not include the API. |
| 403 | storage_quota_exceeded | The plan’s storage space would be exceeded. |
| 404 | not_found | No content with this ID. |
| 409 | busy | The same ID is being sent by another request: try again in a few seconds. |
| 413 | content_too_large | Content or file too large. |
| 413 | too_many_pages | The PDF exceeds the number of pages allowed by the plan. |
| 415 | unsupported_media_type | File format or request type not supported. |
| 422 | no_text | No readable text (scanned PDF, empty file). |
| 422 | unreadable_file | Unreadable or damaged file. |
| 422 | protected_file | Password-protected or encrypted file. |
| 422 | type_mismatch | The file’s content does not match its extension. |
| 422 | content_rejected | Content blocked by the security check: it contains instructions aimed at an AI assistant. |
| 429 | rate_limited | Too many calls with this key: wait for the indicated delay. |
| 429 | daily_volume_exceeded | Daily volume of new or changed content reached for this assistant. |
| 500 | internal_error | Internal error: try again later. |
| 503 | temporarily_unavailable | Service temporarily unavailable: try again after the indicated delay. |
Example with n8n (or Make)
- Create a “Bearer Auth” credential containing the QuickAsk key.
- After the node that reads your data (database, spreadsheet, ERP…), add an “HTTP Request” node using the PUT method, with the URL below and each item’s ID at the end.
- Send a JSON body with the item’s title, text and, if possible, URL and update date.
- Leave about one second between two calls (“Batching” option) to stay under the rate limit. With Make, the “HTTP — Make a request” module is configured the same way.
{
"method": "PUT",
"url": "https://www.quick-ask.app/api/v1/bots/<BOT_ID>/knowledge/{{ $json.id }}",
"authentication": "genericCredentialType",
"genericAuthType": "httpBearerAuth",
"sendBody": true,
"contentType": "json",
"specifyBody": "json",
"jsonBody": "={{ { title: $json.name, content: $json.description, format: 'text', source_url: $json.url, updated_at: $json.updatedAt } }}",
"options": { "batching": { "batch": { "batchSize": 1, "batchInterval": 1100 } } }
}Best practices
- Use a stable ID (your database’s primary key): it is what allows an update rather than a duplicate.
- Send the update date: it helps the assistant prefer the most recent information.
- You can resend your whole catalogue at each sync: unchanged content costs nothing.
- To remove what no longer exists on your side, compare the list (GET) with your data and delete the IDs that have disappeared.
- Keep the key on the server side (never in a web page or a mobile app) and revoke it as soon as it is no longer used.