⚠️ If you’re having issues with Cloudflare blocking our crawlers, read the troubleshooting steps here.

Documents

Conversations

POST /v2/indices/{index public key}/conversations

POST /v2/indices/{index public key}/conversations/{conversation_id}

Ask a question and receive an AI-generated answer based on the content in your index, together with the sources used to create the answer.

Answers are turn-based. The first request starts a new conversation and returns a conversation_id. Sending this ID in the path of the following requests keeps the earlier questions and answers as context. This lets visitors refine or narrow a request without having to repeat it.

These endpoints are also used by the AI Conversations widget.

Please note that the AI Conversations API uses your public SITEKEY, not the secret API key!

Start a new conversation

Send the visitor’s first question without a conversation_id. The response contains the conversation_id to use for every following turn.

Set ai_conversations to true when starting a conversation. Without it, the endpoint returns a single answer that cannot be continued. This results in the response having no question_id, and posting a follow-up question to the returned conversation_id fails.

POST /v2/indices/{index public key}/conversations

{
  "question": "What is AddSearch?",
  "ai_conversations": true
}

Continue a conversation

Add each follow-up question to the same conversation by adding the conversation_id to the path. The question is interpreted in the context of the earlier turns, so references such as “the second one” or “in blue” are resolved against the conversation history.

POST /v2/indices/{index public key}/conversations/bf9e6055-59f7-42ac-8198-5bbc4e85b57b

{
  "question": "What did I ask before this?"
}

Path parameters

ParameterDescriptionTypeNotes
index public keyThe public site keystringA site key is an identifier of your AddSearch account that can be found in the dashboard
conversation_idThe id of an existing conversationstringReturned in the response of the first request of a conversation. Must be exactly 36 characters long. Leave out of the path when starting a new conversation.

Request body parameters

ParameterDescriptionTypeNotes
questionThe visitor's questionstringRequired. 500 characters or less, and cannot be empty.
ai_conversationsEnables a conversation that can be continuedbooleanSet to true when starting a new conversation. If left out, a single answer is returned that cannot be continued. Optional for the following turns of the same conversation.
streamingReturns the answer as a server-sent event streambooleanThe default is false. See "Streaming responses".
filterLimits the documents used to compose the answerobjectUses the same filter syntax as the Search API

The optional parameters of the AI Answers feature can also be used with these endpoints to control how the answer is generated.

Sample request

curl --request POST \
  'https://api.addsearch.com/v2/indices/YOUR_SITEKEY/conversations' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "question": "What is AddSearch?",
    "ai_conversations": true
  }'

Response

Both endpoints return the same response structure.

{
  "response": {
    "conversation_id": "bf9e6055-59f7-42ac-8198-5bbc4e85b57b",
    "question_id": "d058bbb8-f00b-45df-8088-06befafe4e42",
    "answer": "AddSearch is a hosted site search service that indexes your content and returns search results and AI-generated answers.",
    "sources": [
      {
        "id": "69fc685283926a5ec5a15e92e6510e96",
        "title": "Example document title",
        "url": "https://www.example.com/document",
        "last_updated_date": "2018-06-20T23:09:09"
      }
    ]
  },
  "errors": [],
  "status": 200
}

FieldDescriptionTypeNotes
conversation_idThe id of the conversationstring36 characters long. Add it to the path of the following requests to keep the earlier turns as context.
question_idThe id of the questionstringIdentifies a single turn of the conversation. Returned when the conversation was started with ai_conversations set to true.
answerThe generated answerstringFormatted as Markdown
sourcesThe documents the answer was composed fromarray, an array of objectsEmpty when no matching content was found in the index
sources[].idDocument's idstring
sources[].titleDocument's titlestring
sources[].urlDocument's URLstring
sources[].last_updated_dateThe time the document was last updatedstringE.g. "2018-06-20T23:09:09"
errorsThe problems found with the requestarrayEmpty on a successful request
statusThe HTTP status code of the responseint

Store the conversation_id from the first response and reuse it for the whole conversation.

To start a new conversation, for example when a visitor clears the chat history, call the endpoint again without a conversation_id. The response contains the conversation_id to use for every following turn.

Streaming responses

Add "streaming": true to the request body to receive the answer as it is generated. There is no separate streaming endpoint. The URLs are the same for both the first question and the follow-up questions.

{
  "question": "What is AddSearch?",
  "ai_conversations": true,
  "streaming": true
}

The response is a server-sent event stream with the content type text/event-stream. Each event is a JSON object on a data: line, and the type field tells you how to handle it.

data: {"type": "metadata", "question_id": "d058bbb8-...", "conversation_id": "bf9e6055-..."}
data: {"type": "token", "content": "AddSearch is "}
data: {"type": "token", "content": "a hosted site search service"}
data: {"type": "sources", "sources": [{"id": "...", "title": "...", "url": "...", "last_updated_date": "..."}]}
data: {"type": "done", "execution_time": 7.39}

Event typeDescriptionFields
metadataSent first, before any part of the answerquestion_id, conversation_id
tokenA chunk of the answer. Repeated until the answer is complete. Concatenate the content values to build the full answer.content
sourcesThe documents the answer was composed fromsources
token_usageDiagnostic information about the request. Can be ignored by your client.
doneThe final event of a successful stream. Closes the stream.execution_time
errorThe answer could not be generated. The response status stays 200 OK.message

The metadata event is always sent first. Read the conversation_id from this event when using streaming.

Concatenate the content values of the token events to build the full answer.

The done event closes the stream.

Your client may also receive event types that are not listed above. Ignore any event type you do not handle, as new types can be added later without notice.

To show keyword search results next to a conversational answer, use the Refine Query endpoint. It turns the current question and the conversation history into a single search term you can pass to the Search API.

Errors

On a successful request errors, an empty array is returned and status repeats the HTTP status code.

When a request fails, errors lists the problems found, and the fields of a successful response are not present.

The status field is not included in every error response, so use the HTTP status code as the primary signal.

StatusMeaningResponse body
200 OKThe request succeedederrors is an empty array
400 Bad RequestThe request body could not be parsed, or conversation_id is not 36 characters long{"code": 400, "message": "Unable to process JSON"}, or an errors array describing the path parameter
404 Not FoundNo conversation exists for the given conversation_id{"errors": ["Conversation not found"], "status": 404}
405 Method Not AllowedA method other than POST was used{"code": 405, "message": "HTTP 405 Method Not Allowed"}
422 Unprocessable EntityThe question is empty or longer than 500 characters{"errors": ["question is too long"]}
429 Too Many RequestsThe rate limit was exceededEmpty
500 Internal Server ErrorThe request could not be processed. For example, a follow-up question sent to a conversation that was not started with ai_conversations set to true.{"errors": [...], "status": 500}

When streaming, a failure that happens before the stream opens is returned as an ordinary HTTP error response.

Once the stream is open, failures arrive as an event with the type error and a message field, while the response status stays 200 OK.

Always check the event types as you read the stream instead of relying on the status code alone.

Rate limits

This endpoint is limited to 5 requests per second from one IP address. Requests exceeding the limit return a 429 Too Many Requests response with an empty body. If rejected, throttle concurrent requests in your client and retry after a short delay. See Rate limits for details.