GlexirDocs
Dashboard

API

Conversations

A conversation stores the items of a multi-turn exchange on the server. Pass its ID as conversation to responses.create(). The conversation's items are prepended to your input, and the new input and output are appended to it. You don't need to replay history or chain response IDs.

The endpoints are OpenAI-compatible, under https://api.glexir.com/v1/conversations.

Quick start

import Glexir from "@glexir/sdk";

const glexir = new Glexir({ apiKey: process.env.GLEXIR_API_KEY });

const conversation = await glexir.conversations.create({ metadata: { topic: "support" } });

const first = await glexir.responses.create({
  model: "gpt-5.4-mini",
  conversation: conversation.id,
  input: "My name is Ada.",
});

const second = await glexir.responses.create({
  model: "gpt-5.4-mini",
  conversation: conversation.id,
  input: "What is my name?",
});

console.log(first.output_text);
console.log(second.output_text);

Operations

SDK methodHTTPReturns
conversations.create(body?, options?)POST /v1/conversationsConversation
conversations.retrieve(id, options?)GET /v1/conversations/{id}Conversation
conversations.update(id, body, options?)POST /v1/conversations/{id}Conversation
conversations.delete(id, options?)DELETE /v1/conversations/{id}ConversationDeleted
conversations.items.create(id, params, options?)POST /v1/conversations/{id}/itemsConversationItemList
conversations.items.list(id, query?, options?)GET /v1/conversations/{id}/itemsPagePromise<ConversationItem>
conversations.items.retrieve(id, itemId, query?, options?)GET /v1/conversations/{id}/items/{itemId}ConversationItem
conversations.items.delete(id, itemId, options?)DELETE /v1/conversations/{id}/items/{itemId}Conversation

Every method takes request options as its last argument. Conversations are not billed by themselves; you pay for the responses that use them.

A conversation belongs to the Glexir organization that created it. Using another conversation ID with any of these endpoints, or with responses.create(), returns 404 (No conversation found with id '...').

The Conversation object

Conversation
idstringoptional
The conversation ID, for example conv_....
object"conversation"optional
Always conversation.
created_atnumberoptional
Unix timestamp in seconds.
metadataRecord<string, string> | nulloptional
Your key/value pairs.
_request_idstring | nulloptional
Added by the SDK: the x-request-id header.

Create a conversation

conversations.create(body?, options?). Both fields are optional.

TypeScript
import Glexir from "@glexir/sdk";

const glexir = new Glexir();

const conversation = await glexir.conversations.create({
  metadata: { customer: "acme" },
  items: [
    { role: "developer", content: "You are a support agent for Acme." },
    { role: "user", content: "Hi, I need help with my order." },
  ],
});

console.log(conversation.id);
ConversationCreateParams
itemsResponseInputItem[] | nulloptional
Initial items, at most 20. Same item types as Responses input.
metadataRecord<string, string> | nulloptional
Up to 16 key/value pairs. Keys up to 64 characters, values up to 512.

The gateway forwards only items and metadata; other fields are dropped. Items go through the same checks as Responses input: audio parts and items from OpenAI-hosted tools return 400 unsupported_on_glexir, and file_id references must be files you uploaded through Glexir. See Input the gateway rejects.

Retrieve a conversation

TypeScript
import Glexir from "@glexir/sdk";

const glexir = new Glexir();

const conversation = await glexir.conversations.retrieve("conv_123");
console.log(conversation.metadata);

Update a conversation

conversations.update(conversationId, body, options?) replaces the metadata. Metadata is the only field you can change.

TypeScript
import Glexir from "@glexir/sdk";

const glexir = new Glexir();

const conversation = await glexir.conversations.update("conv_123", { metadata: { status: "resolved" } });
console.log(conversation.metadata);

ConversationUpdateParams is { metadata: Record<string, string> | null }. metadata is required; without it the gateway returns 400 ("metadata is required.").

Delete a conversation

TypeScript
import Glexir from "@glexir/sdk";

const glexir = new Glexir();

const deleted = await glexir.conversations.delete("conv_123");
console.log(deleted.deleted);

Returns ConversationDeleted: { id, deleted, object: "conversation.deleted" }. Deleting a conversation does not delete its items. After deletion the ID returns 404 on Glexir.

Add items

conversations.items.create(conversationId, params, options?) appends up to 20 items.

TypeScript
import Glexir from "@glexir/sdk";

const glexir = new Glexir();

const added = await glexir.conversations.items.create("conv_123", {
  items: [{ role: "user", content: "Also, can I change the delivery address?" }],
});

console.log(added.data.map((item) => item.id));
ItemCreateParams
itemsResponseInputItem[]required
The items to add, at most 20.
includeResponseIncludable[]optional
Extra fields to include in the returned items. Sent as a query parameter.

Returns ConversationItemList: { object: "list", data, first_id, last_id, has_more }. The same input checks as create() apply.

List items

conversations.items.list(conversationId, query?, options?) returns a PagePromise<ConversationItem>. Iterate it with for await to walk every page, or await it for one page. Items are newest first unless you pass order: "asc". See Pagination.

TypeScript
import Glexir from "@glexir/sdk";

const glexir = new Glexir();

for await (const item of glexir.conversations.items.list("conv_123", { order: "asc" })) {
  if (item.type === "message") console.log(item.role, item.content);
}
ItemListParams
afterstringoptional
Cursor: list items after this one. The SDK fills it in from last_id while paging.
limitnumberoptional
Items per page.
order"asc" | "desc"optionaldefault "desc"
Sort order.
includeResponseIncludable[]optional
Extra fields to include.

ConversationItem is the same type as ResponseItem: messages, reasoning items, function and custom tool calls with their outputs, and compaction items. Conversation messages may also use a plain text content part.

Retrieve an item

TypeScript
import Glexir from "@glexir/sdk";

const glexir = new Glexir();

const item = await glexir.conversations.items.retrieve("conv_123", "msg_456");
console.log(item.type);

conversations.items.retrieve(conversationId, itemId, query?, options?). ItemRetrieveParams is { include?: ResponseIncludable[] }.

Delete an item

TypeScript
import Glexir from "@glexir/sdk";

const glexir = new Glexir();

const conversation = await glexir.conversations.items.delete("conv_123", "msg_456");
console.log(conversation.id);

conversations.items.delete(conversationId, itemId, options?) removes the item and returns the updated Conversation.

Using a conversation with Responses

  • Pass conversation: "conv_123" or conversation: { id: "conv_123" } to responses.create().
  • Do not combine conversation with previous_response_id.
  • Before running a request with a conversation, Glexir reserves credit for about 50,000 tokens of earlier context, because it does not track the conversation's size. The reservation is released and you pay only for actual usage. If your balance is low, this reservation can cause a 402.
  • Every file and response referenced in the request must live on the same upstream account as the conversation. Otherwise the request fails with 409 cross_account_reference.

Errors

StatuscodeCause
400unsupported_on_glexirAn item contains audio input or comes from an OpenAI-hosted tool.
400nullMissing metadata on update, or an items value that is not an array of objects.
404nullThe conversation or a referenced file is not yours.
409cross_account_referenceReferenced objects live on different upstream accounts.

See HTTP error codes for errors every endpoint can return.