Sending a text
POST /v1/prisms/{prism}/results
One call answers one text. {prism} is the prism's slug or id, and the body is JSON:
| Key | Type | Required | What it does |
|---|---|---|---|
fields |
object | This or text |
One string per field of the prism version, keyed by field key. |
text |
string | This or fields |
Shorthand for a prism whose only field is text. |
ref |
string | No | Your reference for the text, returned with the result. 1 to 200 characters. |
version |
integer | No | The prism version to answer with. The latest saved version by default. |
idempotency_key |
string | No | Makes the call safe to repeat. 1 to 200 characters. |
Send Content-Type: application/json. Every key is snake_case, and the API ignores keys it doesn't know, so a misspelled idempotencyKey does nothing and raises no error.
fields
Section titled “fields”fields must hold exactly the field keys of the prism version, no more and no fewer. Every value is a string. Send an empty string for a field you have nothing for.
{ "fields": { "subject": "Charged twice this month", "text": "Hi, I was billed twice for September. Please refund the second charge before Friday." }}A missing or extra key answers 400 and nothing is saved:
| You send | message |
|---|---|
fields without subject |
Missing fields: subject |
fields with an extra body |
Unknown fields: body |
| A number instead of a string | Invalid request: fields.subject: Expected string, received number |
The text shorthand
Section titled “The text shorthand”A prism whose only field is text also takes the text on its own:
{ "text": "Hi, I was billed twice for September. Please refund the second charge before Friday." }The API turns it into {"fields": {"text": "..."}}. Send one of fields and text. Both, or neither, answers 400 with Invalid request: fields: send either fields or text. support-routing has two fields, so {"text": "..."} answers 400 with Missing fields: subject.
Reference (ref)
Section titled “Reference (ref)”Put your own id for the text in the reference, ref, such as a ticket number. It comes back in the response and in every CSV, TSV and JSON Lines row, so you can match results to your records. It does not have to be unique. Leading and trailing spaces are trimmed.
Context for one call (context)
Section titled “Context for one call (context)”A prism's context is the same for every call. When part of the background changes per call, such as each client's billing guideline or refund policy, send it as context:
{ "text": "Conf with J. Smith re strategy, 1.5h", "context": "Acme Corp guideline: no charges for internal conferences between firm lawyers."}The model reads the prism's context, then a line Context for this call:, then yours. Say in the prism's context or questions which one wins when they disagree, for example "Where the context for this call conflicts with the rules above, it wins."
- It is optional. An empty or blank value is the same as leaving it out.
- It counts toward the size of the call. See Size limits.
- It is saved with the result and shown on the result's page in the app. The API does not return it, and no row or download holds it.
- A repeated
idempotency_keyreturns the stored result, whatevercontextthe repeat sends. A retry sends the stored context again.
Pinning a version
Section titled “Pinning a version”A call runs the latest saved version of the prism. The response's version tells you which one answered.
When someone saves a new version in the app, the next call runs it. That is what you want for a question rewrite. It breaks your integration when the new version adds or removes a field, because your code still sends the old keys. Pin the version to keep the field set steady until your code catches up:
{ "version": 3, "fields": { "subject": "Charged twice this month", "text": "Hi, I was billed twice for September. Please refund the second charge before Friday." }}A pinned call sends the field keys of that version. A version that does not exist answers 404 with Prism version not found. The Lens is not part of a version, so a pinned call still gets the prism's current Lens in json.
idempotency_key
Section titled “idempotency_key”With an idempotency_key, repeating the call returns the stored result instead of answering the text again. Use a key derived from your record, such as tck-8812-1, and send it on every call you might repeat. Errors and retries has the rules, including how unique a key must be.
Size limits
Section titled “Size limits”- Each field value is at most 100,000 characters, enough for a whole call transcript. A longer one answers
400withInvalid request: fields.text: String must contain at most 100000 character(s). - The fields, the prism's context, the call's
contextand the longest question must fit in about 26,000 tokens together. Prismlet counts four characters of their JSON as one token, which comes to about 104,000 characters, and the more context and question text the prism has, the less room is left for the fields. Over the budget, the call answers400withRequest too large: about 27100 tokens of fields, context and the longest question, the limit is 26000. Prismlet's estimate is four characters per token, and text that is not English, or has many numbers or symbols, uses more real tokens, so a call close to the budget can still be refused by the model provider and come back as a failed result. contextis at most 100,000 characters. A longer one answers400withInvalid request: context: String must contain at most 100000 character(s).- The whole body is at most 1 MiB. A larger body answers
413.
Nothing is saved and nothing reaches the model when a call fails one of these checks. Limits lists every limit in one table.
Timeouts
Section titled “Timeouts”The call waits for the answers. Each attempt to reach the model has 15 seconds by default. A 429 or a 5xx from the model gets one more attempt. A timeout, a network error or any other error from the model fails the call at once. So a call can take about 30 seconds before it fails. Set your client timeout above that. The examples in these docs use 45 seconds.
curl --max-time 45 ...await fetch(url, { ...options, signal: AbortSignal.timeout(45_000) });requests.post(url, json=body, headers=headers, timeout=45)A call that runs out of time on the model's side is saved as a failed result and answers 502.