API Examples
Copy-paste starter code for interacting with your Interlocute node in cURL, C#, and JavaScript.
my-node with your node's alias from the dashboard. Your node's base URL is https://my-node.interlocute.ai.
cURL: Send a message
curl -X POST https://my-node.interlocute.ai/chat \
-H "Authorization: Bearer $INTERLOCUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Hello! What can you do?"
}'cURL: Continue a thread
curl -X POST https://my-node.interlocute.ai/chat \
-H "Authorization: Bearer $INTERLOCUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Tell me more about that.",
"threadId": "thr_abc123"
}'cURL: Stream a response
curl -N -X POST https://my-node.interlocute.ai/chat/stream \
-H "Authorization: Bearer $INTERLOCUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Write a haiku about AI."
}'-N flag disables buffering so you see tokens as they arrive.
cURL: Fetch node info (/chit)
# JSON (default)
curl https://my-node.interlocute.ai/chit/identity
# Plain text
curl -H "Accept: text/plain" https://my-node.interlocute.ai/chit/identity
# Markdown
curl -H "Accept: text/markdown" https://my-node.interlocute.ai/chit/identitycURL: Submit, request cancellation, and read the outcome
Use direct Async chat when your integration needs a receipt it can poll and cancel. This example uses your own Node-scoped ID, so you can find the same invocation even if its submission or cancellation response is lost. Choose a new external ID for each intended job.
# 1. Submit once, using a stable ID for this job
curl -X POST "https://my-node.interlocute.ai/chat" \
-H "Authorization: Bearer $INTERLOCUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"externalInvocationId": "orders:job-123",
"content": "Summarize this order status: dispatched and awaiting delivery.",
"options": { "responseMode": "Async" }
}'
# 2. If you decide to cancel, request it against the original ID
curl -i -X POST "https://my-node.interlocute.ai/chit/by-external-id/cancel?externalInvocationId=orders%3Ajob-123" \
-H "Authorization: Bearer $INTERLOCUTE_API_KEY"
# 3. Read the same receipt; repeat this GET while terminal is false
curl -G "https://my-node.interlocute.ai/chit/by-external-id" \
-H "Authorization: Bearer $INTERLOCUTE_API_KEY" \
--data-urlencode "externalInvocationId=orders:job-123"cancel_requested is recorded intent, not confirmation that
work or billing stopped. HTTP 200 returns a settled receipt; inspect its status and
cancellationConfirmedAtUtc.
If the POST times out or returns 503, retry that same cancellation or GET, preserving the job ID.
Do not submit a second paid job to find out what happened.
GET returns top-level status, terminal
and outputs. Continue polling during cancel_requested.
An unresolved receipt is terminal local observation with an unknown upstream outcome;
keep its ID for later readback and do not automatically replay it. Recorded charges and any finalized late result remain on
the original receipt. See the full cancellation reference.
C#: Send a message
using var http = new HttpClient();
http.BaseAddress = new Uri("https://my-node.interlocute.ai/");
http.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue(
"Bearer", Environment.GetEnvironmentVariable("INTERLOCUTE_API_KEY"));
var response = await http.PostAsJsonAsync(
"chat",
new { content = "Hello from C#!" });
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);C#: Continue a thread
var response = await http.PostAsJsonAsync(
"chat",
new
{
content = "Follow up question...",
threadId = "thr_abc123"
});
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine(result);C#: Request cancellation by invocation ID
Using the authenticated HttpClient above and the ID from the Async acceptance response:
var invocationId = "01JX4K7M2N...";
var receiptPath = $"chit/{Uri.EscapeDataString(invocationId)}";
using var cancellation = await http.PostAsync($"{receiptPath}/cancel", content: null);
if (cancellation.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable)
{
throw new InvalidOperationException(
"Retry cancellation or GET the original receipt; do not resubmit the job.");
}
cancellation.EnsureSuccessStatusCode();
Console.WriteLine(await cancellation.Content.ReadAsStringAsync());
// 202 records intent. Continue GET polling receiptPath while terminal is false.JavaScript: Send a message
const response = await fetch(
"https://my-node.interlocute.ai/chat",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INTERLOCUTE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ content: "Hello from JS!" }),
}
);
const data = await response.json();
console.log(data);JavaScript: Stream a response
const response = await fetch(
"https://my-node.interlocute.ai/chat/stream",
{
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.INTERLOCUTE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ content: "Stream me a story." }),
}
);
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
process.stdout.write(decoder.decode(value));
}JavaScript: Request cancellation by invocation ID
async function requestCancellation(invocationId) {
const url = `https://my-node.interlocute.ai/chit/${encodeURIComponent(invocationId)}/cancel`;
const response = await fetch(url, {
method: "POST",
headers: { Authorization: `Bearer ${process.env.INTERLOCUTE_API_KEY}` },
});
if (response.status === 503) {
throw new Error("Retry cancellation or GET the original receipt; do not resubmit the job.");
}
if (!response.ok) throw new Error(`Cancellation HTTP ${response.status}`);
return { httpStatus: response.status, receipt: await response.json() };
}
const { httpStatus, receipt } = await requestCancellation("01JX4K7M2N...");
console.log(httpStatus, receipt.status, receipt.terminal);
// Continue GET polling the original receipt while terminal is false.
// An unresolved outcome must not be automatically replayed.Aborting a local fetch only stops your client from waiting. To cancel an accepted Async job, call the POST above. Repeat the same request after a lost response; cancellation preserves the first durable request timestamp.
Best practices
- Timeouts — a client timeout does not cancel an accepted Async job. Keep its receipt ID, poll for the outcome, or explicitly request cancellation.
- Retries — retry receipt GETs and the same cancellation POST with backoff after a 503 or lost response. Do not automatically replay an invocation with an unknown outcome. Correct ID/authentication/scope errors before retrying.
- Idempotency — for direct Async submission, supply
externalInvocationIdin the body. An identical submission with that same ID recovers the original job; changing the request with the same ID is rejected. See submission retry rules. - Log request IDs — response headers include a request ID. Log it for debugging and support requests.
Next steps
- Security & Data — data handling and governance
- FAQ — common questions answered