Виконайте флоу і прочитайте його виклики моделі
Надішліть запит через флоу, прив’язаний до коду операції, прочитайте операції — виклики моделі у флоу — з усіма спробами за ними й отримайте список холдів цих викликів.
Дві речі на цій сторінці мають одне ім’я. Запит до флоу називає код операції, і POST /v1/operations/execute виконує флоу, прив’язаний до цього коду. Операція — це ще й запис про один виклик моделі у флоу; два читання цієї сторінки показують список таких записів і один запис з усіма спробами за ним. Остання операція сторінки показує список холдів цих викликів. Консоль показує ті самі записи на сторінці Операції, на її вкладці Операції — екран описано в статті Операції, авторизації та реєстр.
Виконання та операція
POST /v1/operations/executeвідповідає виконанням: одним проходом флоу, яке називаєexecution_id. Виконання читають знову черезGET /v1/executions/{id}/statusіGET /v1/executions/{id}.Операція — це один виклик моделі, який називає
operation_id. Одна операція відкривається на кожен виклик моделі, який робить флоу.Ідентифікатор виконання — не ідентифікатор операції: на нього
GET /v1/operations/{id}відповідає404з кодомoperation_not_found.
Запис про виклик моделі
Операція відкривається, коли вузол AI-модель ось-ось викличе модель, після того як гроші на виклик зарезервовано. Вона починається зі статусу pending і закінчується одним із трьох статусів.
| Статус | Що він означає |
|---|---|
completed | Модель відповіла |
failed | Виклик закінчився без відповіді моделі |
uncertain | Невідомо, чим закінчився виклик: провайдер не відповів вчасно або прийняв виклик на виконання у фоні, і його не вдалося про цей виклик спитати |
Холд виклику зі статусом uncertain не повертається одразу: провайдерові, можливо, уже заплатили, тому холд тримається, доки не спливе. Такий виклик Slen теж не повторює. Коли відповідь на виклик втрачено, про це повідомляє подія вебхука operation.uncertain. Виклик, який провайдер виконує у фоні, теж повідомляє, чим він закінчився: operation.completed — коли провайдер відповів, operation.failed — коли виклик не вдався, operation.uncertain — коли спитати провайдера про виклик більше не вдалося. Щоб знайти виклики з невідомим результатом без вебхука, виберіть операції за статусом, як у прикладі нижче.
Спроба — це один виклик одного підключення провайдера. Коли пул моделі після збою переходить до іншого підключення, операція отримує наступну спробу з черговим номером. Спроба каже, яке підключення та яку модель вона використала і чим вона закінчилася. Її cost залишається null, доки виклик не закрито.
Список містить операції проєкту ключа, спершу найновіші. Спроб він не показує:
attemptsтам — порожній список. Щоб їх побачити, прочитайте одну операцію.Операція не зберігає ні промпт, ні відповідь моделі.
Спроба називає своє підключення і свій пул:
connection_nameіpool_name, поряд із ними —providerіconnection_deleted. Назва дорівнюєnull, якщо пул відтоді видалено (pool_idлишається) або якщо підключення чи пул поза досяжністю ключа. Видалене підключення зберігає назву.finish_reason— чому провайдер зупинився, так, як він це повідомив.flow_executionназиває виконання й вузол, викликом моделі якого є операція:execution_id,flow_idіnode_key. Коли виконання поза досяжністю ключа, цеnull, і це поле є лише під час читання однієї операції, не в списку.
Пошук і нумеровані сторінки
q шукає в списку. Цифри, які є ID операції проєкту, знаходять саме цю операцію, хоч би якою старою вона була: вікно from і to до неї не застосовується, а status і operation_code — застосовуються. Будь-який інший текст знаходить операції, у яких external_user_id дорівнює цьому тексту або починається з нього, всередині вікна; % і _ там — звичайні символи. На q довший за 190 символів відповідь — 422. Значення входить в адресу, тому external_user_id, який є адресою e-mail, потрапляє в історію браузерів і в журнали доступу.
Список читають курсором, як будь-який список, — Список сторінками, — або за номером сторінки. Надішліть page, і в meta прийдуть page, limit, total і anchor. total рахується до 10 000; далі він лишається 10 000, а total_capped дорівнює true. Надсилайте anchor першої сторінки з усіма іншими сторінками: рахуються лише операції з ID не більшим за нього, тому операція, відкрита за цей час, не зсуває рядки зі сторінки на сторінку. На page разом із cursor і на anchor без page відповідь — 422.
Холди викликів
GET /v1/authorizations показує список холдів проєкту, найновіші — першими: по одному на кожен виклик моделі, з тим, скільки виклик мав коштувати, скільки було зарезервовано і скільки списано. Він потребує дозволу read і читає вікно не довше за сім днів, як список операцій, — курсором або за номером сторінки. operation_code лишає холди одного коду операції. Що означає кожен статус холду, пояснює стаття Як працює резервування бюджету, а консоль показує ті самі холди на вкладці Авторизації екрана Операції.
Операції
Описи операцій і полів подано англійською.
Запустити флоу, прив’язаний до операції
POST /v1/operations/execute
- Дозвіл:
gateway:write - Потрібен Idempotency-Key
- Доступно в SDK для PHP і Node.js
The caller names what it wants done, never a model or a pool. Answers 202 when the flow parked at a queue or approval node — waiting_on says on what — and also when execution_mode: async handed the run to a queue worker, where the status is queued and nothing has walked yet. Both carry retry_after_seconds. Idempotent.
The Idempotency-Key belongs to the execution it opened, and no copy of the answer is kept beside it: a repeated key with the same body is answered from that execution as it is now (replayed: true) and runs nothing. 202 with retry_after_seconds while it has not finished — queued, waiting, or running when the retry met a walk still under way (a synchronous run may outlast the caller's timeout) — and 200 with the outcome once it has: output of a completed run, error_code and error_message of one that was refused or failed, even when the first answer was an error envelope — error repeats the two as {code, message}, on a replay exactly as on the first answer. The same key with a different body is 409 idempotency_conflict.
A flow that refuses is not an HTTP error: a reject node answers 200 with status: rejected. A walk that throws is one: the execution is closed — failed, rejected when the gateway refused to spend (policy_denied, customer_blocked, budget_exceeded, insufficient_credits, an overrun), uncertain when the provider's answer was lost — with the same code in its error_code, and the answer is the error envelope with the status of what threw. The code of the envelope and the code of the row are one and the same, also for what is wrong with the setup rather than refused by a policy: customer_not_found (404), model_not_allowed (403), cost_calculation_failed (422) and ledger_unavailable (503) close the execution failed with that code.
A synchronous run that outlives the running ceiling (15 minutes by default) is closed failed with execution_lost while its walk is still under way. Whatever that walk goes on to compute is not the outcome of the execution, and the call is answered with the execution as its row has it — 200, failed, execution_lost, no output, replayed: false — exactly what a repeated key is told afterwards. A model call the walk did make is paid for, and cost.actual arrives.
A model node routes a refusal to spend into its deny port when something is connected to it — policy_denied, customer_blocked, budget_exceeded, insufficient_credits, overrun_stopped — and then the flow decides what the caller hears. The setup errors above are never routed.
403 customer_blocked — the context.user_id names a customer that is blocked (POST /v1/customers/{externalUserId}/block). Nothing is created: no execution, no hold. A repeated key of an execution opened before the block is still answered by that execution. A run already under way — queued, or parked at an approval — meets the block at its next model node that takes credits: the hold is refused, and the execution closes rejected with customer_blocked (a model node with something on its deny port routes it there, like a policy refusal). A run whose operation has no price in credits takes no hold and finishes.
404 flow_not_found — no flow is bound to the operation, the flow was never published, or it is archived. Nothing is created for such a call — no execution, no hold — so the same key runs once the flow is un-archived. An execution parked before its flow was archived still finishes, and the key of an execution that exists is answered by it whatever became of the flow or its binding since: the 404 is for a key that opened nothing.
Параметри
| Параметр | Опис |
|---|---|
Idempotency-Key обовʼязковоheader | Replay guard for a financial write. The same key returns the original result with the original status and never charges twice; a different body under a used key answers
|
Тіло запиту
{
"operation": "generate_email",
"input": {},
"context": {
"user_id": "74438200973594624",
"credit_type": "default"
},
"execution_mode": "sync"
}Відповіді
The finished run
{
"data": {
"execution_id": "74438200973594624",
"status": "running",
"operation": "generate_email",
"output": {},
"error_code": "string",
"error_message": "string",
"cost": {
"estimated": "0.02700000",
"actual": "0.02700000"
},
"cache": {
"hit": true,
"cached_at": "2026-10-02T09:30:00Z"
},
"waiting_on": {
"node_key": "string",
"type": "queue_node",
"resume_at": "2026-10-02T09:30:00Z"
},
"trace_url": "string",
"retry_after_seconds": 1,
"error": {
"code": "string",
"message": "string"
},
"replayed": true
}
}The run has not finished: it parked, was queued, or — on a repeated key — is still walking. Come back after retry_after_seconds.
{
"data": {
"execution_id": "74438200973594624",
"status": "running",
"operation": "generate_email",
"output": {},
"error_code": "string",
"error_message": "string",
"cost": {
"estimated": "0.02700000",
"actual": "0.02700000"
},
"cache": {
"hit": true,
"cached_at": "2026-10-02T09:30:00Z"
},
"waiting_on": {
"node_key": "string",
"type": "queue_node",
"resume_at": "2026-10-02T09:30:00Z"
},
"trace_url": "string",
"retry_after_seconds": 1,
"error": {
"code": "string",
"message": "string"
},
"replayed": true
}
}Помилки
| Статус | Коди | Коли |
|---|---|---|
| 400 | Malformed request — e.g. the | |
| 401 | No credential, or one that is not valid | |
| 402 | Refused because of money: | |
| 403 | Authenticated, but not allowed: scope ( | |
| 404 | No such resource for this tenant. Somebody else's resource — and a resource of a project the caller does not reach — answers the same way on purpose: the two must not be distinguishable. | |
| 409 | State conflict: idempotency clash, stale draft, illegal transition; the last owner of an organization ( | |
| 422 | Validation failure or a semantically impossible request. Field-level validation from the framework answers | |
| 429 | Rate limited for this API key | |
| 500 | The walk broke and the execution is closed as | |
| 502 | The walk broke and the execution is closed as | |
| 503 | The walk broke and the execution is closed as | |
| 504 | The walk broke and the execution is closed as |
Заголовки
X-Request-IdRetry-After429
Тіло кожної помилки — конверт помилки.
Список операцій
GET /v1/operations
- Дозвіл:
read
Параметри
| Параметр | Опис |
|---|---|
cursor необовʼязковоquery | The |
limit необовʼязковоquery | Page size (default 30).
|
page необовʼязковоquery | The page number, from 1. Turns the list into its numbered form: the answer's
|
anchor необовʼязковоquery | The
|
q необовʼязковоquery | Search. Digits that are the id of an operation of the project find exactly that operation, past the window — the id carries its own moment, so
|
operation_code необовʼязковоquery |
|
status необовʼязковоquery |
|
from необовʼязковоquery | Window start, ISO-8601 — a value with an offset is the moment it names, one without is read as UTC. The rule of the three lists that take this parameter (
|
to необовʼязковоquery | Window end, ISO-8601, inclusive. See
|
Відповіді
One page of operations — a cursor page, or a numbered one with page
{
"data": [
{
"operation_id": "74438200973594624",
"operation_code": "generate_email",
"external_user_id": "user_8421",
"status": "pending",
"attempts": [
{
"attempt_id": "74438200973594624",
"attempt_number": 1,
"connection_id": "74438200973594624",
"pool_id": "74438200973594624",
"model_code": "gpt-4o-mini",
"model_price_id": "74438200973594624",
"status": "pending",
"error_code": "string",
"provider_request_id": "74438200973594624",
"input_tokens": 1,
"output_tokens": 1,
"cost": "0.02700000",
"cost_multiplier": "string",
"latency_ms": 1,
"started_at": "2026-10-02T09:30:00Z",
"completed_at": "2026-10-02T09:30:00Z",
"pool_name": "string",
"connection_name": "string",
"connection_deleted": true,
"provider": "string",
"finish_reason": "string"
}
],
"created_at": "2026-10-02T09:30:00Z",
"updated_at": "2026-10-02T09:30:00Z",
"flow_execution": {
"execution_id": "74438200973594624",
"flow_id": "74438200973594624",
"node_key": "string"
}
}
],
"meta": {
"limit": 1,
"next_cursor": "string"
}
}Помилки
| Статус | Коди | Коли |
|---|---|---|
| 401 | No credential, or one that is not valid | |
| 403 | Authenticated, but not allowed: scope ( | |
| 422 | Validation failure or a semantically impossible request. Field-level validation from the framework answers |
Заголовки
X-Request-Id
Тіло кожної помилки — конверт помилки.
Один запит з усіма спробами провайдерів
GET /v1/operations/{id}
- Дозвіл:
read
The way to find out what an uncertain operation actually did.
Параметри
| Параметр | Опис |
|---|---|
id обовʼязковоpath | Snowflake identifier, as a string.
|
Відповіді
The operation and its attempts
{
"data": {
"operation_id": "74438200973594624",
"operation_code": "generate_email",
"external_user_id": "user_8421",
"status": "pending",
"attempts": [
{
"attempt_id": "74438200973594624",
"attempt_number": 1,
"connection_id": "74438200973594624",
"pool_id": "74438200973594624",
"model_code": "gpt-4o-mini",
"model_price_id": "74438200973594624",
"status": "pending",
"error_code": "string",
"provider_request_id": "74438200973594624",
"input_tokens": 1,
"output_tokens": 1,
"cost": "0.02700000",
"cost_multiplier": "string",
"latency_ms": 1,
"started_at": "2026-10-02T09:30:00Z",
"completed_at": "2026-10-02T09:30:00Z",
"pool_name": "string",
"connection_name": "string",
"connection_deleted": true,
"provider": "string",
"finish_reason": "string"
}
],
"created_at": "2026-10-02T09:30:00Z",
"updated_at": "2026-10-02T09:30:00Z",
"flow_execution": {
"execution_id": "74438200973594624",
"flow_id": "74438200973594624",
"node_key": "string"
}
}
}Помилки
| Статус | Коди | Коли |
|---|---|---|
| 401 | No credential, or one that is not valid | |
| 403 | Authenticated, but not allowed: scope ( | |
| 404 | No such resource for this tenant. Somebody else's resource — and a resource of a project the caller does not reach — answers the same way on purpose: the two must not be distinguishable. |
Заголовки
X-Request-Id
Тіло кожної помилки — конверт помилки.
Список холдів
GET /v1/authorizations
- Дозвіл:
read
Параметри
| Параметр | Опис |
|---|---|
cursor необовʼязковоquery | The |
limit необовʼязковоquery | Page size (default 30).
|
page необовʼязковоquery | The page number, from 1. Turns the list into its numbered form: the answer's
|
anchor необовʼязковоquery | The
|
operation_code необовʼязковоquery |
|
from необовʼязковоquery | Window start, ISO-8601 — a value with an offset is the moment it names, one without is read as UTC. The rule of the three lists that take this parameter (
|
to необовʼязковоquery | Window end, ISO-8601, inclusive. See
|
Відповіді
One page of reservations — a cursor page, or a numbered one with page
{
"data": [
{
"reservation_id": "74438200973594624",
"status": "authorized",
"model_code": "gpt-4o-mini",
"operation_code": "generate_email",
"external_user_id": "user_8421",
"idempotency_key": "order-42:email",
"estimated_cost": "0.02700000",
"reserved_amount": "0.02700000",
"captured_amount": "0.02700000",
"overrun_amount": "0.02700000",
"estimated_input_tokens": 1,
"estimated_output_tokens": 1,
"max_output_tokens": 1,
"safety_multiplier": "string",
"estimation_strategy": "fixed",
"model_price_id": "74438200973594624",
"customer_hold_id": "74438200973594624",
"customer_hold_credits": "12.5000",
"currency": "USD",
"expires_at": "2026-10-02T09:30:00Z",
"created_at": "2026-10-02T09:30:00Z"
}
],
"meta": {
"limit": 1,
"next_cursor": "string"
}
}Помилки
| Статус | Коди | Коли |
|---|---|---|
| 401 | No credential, or one that is not valid | |
| 403 | Authenticated, but not allowed: scope ( | |
| 422 | Validation failure or a semantically impossible request. Field-level validation from the framework answers |
Заголовки
X-Request-Id
Тіло кожної помилки — конверт помилки.
Приклади
Виконати флоу
Флоу, прив’язаний до generate_email, відповів одразу, тому статус — completed, а в output лежить те, що повернув флоу. cost.actual тут — null: виклик моделі закривається після відповіді.
curl https://api.slen.ai/api/v1/operations/execute \
-H "Authorization: Bearer $SLEN_API_KEY" \
-H "Idempotency-Key: order-42:email" \
-H "Content-Type: application/json" \
-d '{
"operation": "generate_email",
"input": {
"messages": [
{
"role": "user",
"content": "Write a short follow-up email."
}
]
}
}'{
"data": {
"execution_id": "74438200973594700",
"status": "completed",
"operation": "generate_email",
"output": {
"model": "gpt-4o",
"content": "Hi Ada, just checking in on the proposal I sent last week.",
"finish_reason": "stop",
"tool_calls": null,
"usage": {
"input_tokens": 14,
"output_tokens": 16,
"cached_input_tokens": 0
}
},
"error": null,
"error_code": null,
"error_message": null,
"cost": {
"estimated": "0.00412500",
"actual": null
},
"cache": {
"hit": false,
"cached_at": null
},
"replayed": false,
"waiting_on": null,
"trace_url": "/v1/executions/74438200973594700"
}
}Знайти виклики з невідомим результатом
Фільтр залишає операції зі статусом uncertain одного коду операції, ID клієнта яких починається з user_84, на першій нумерованій сторінці. Серед них — один виклик для user_8421.
curl "https://api.slen.ai/api/v1/operations?q=user_84&operation_code=generate_email&status=uncertain&page=1" \
-H "Authorization: Bearer $SLEN_API_KEY"{
"data": [
{
"operation_id": "74442181054119936",
"operation_code": "generate_email",
"external_user_id": "user_8421",
"status": "uncertain",
"attempts": [],
"created_at": "2026-10-02T09:12:04+00:00",
"updated_at": "2026-10-02T09:13:04+00:00"
}
],
"meta": {
"limit": 30,
"page": 1,
"total": 1,
"total_capped": false,
"anchor": "74442181054119936"
}
}Прочитати виклик із його спробами
Виклик мав одну спробу, через пул Primary. Підключення не відповіло вчасно, тому спроба — uncertain, і в ній немає ні токенів, ні вартості, ні finish_reason. Виклик — це виклик моделі вузла model одного флоу, і flow_execution називає його виконання.
curl https://api.slen.ai/api/v1/operations/74442181054119936 \
-H "Authorization: Bearer $SLEN_API_KEY"{
"data": {
"operation_id": "74442181054119936",
"operation_code": "generate_email",
"external_user_id": "user_8421",
"status": "uncertain",
"attempts": [
{
"attempt_id": "74442181058314240",
"attempt_number": 1,
"connection_id": "74438912450035712",
"pool_id": "74438955400675328",
"model_code": "gpt-4o-mini",
"model_price_id": "1108",
"status": "uncertain",
"error_code": "operation_uncertain",
"provider_request_id": null,
"input_tokens": null,
"output_tokens": null,
"cost": null,
"cost_multiplier": "1.0000",
"latency_ms": 60004,
"started_at": "2026-10-02T09:12:04+00:00",
"completed_at": "2026-10-02T09:13:04+00:00",
"pool_name": "Primary",
"connection_name": "OpenAI production",
"connection_deleted": false,
"provider": "openai",
"finish_reason": null
}
],
"created_at": "2026-10-02T09:12:04+00:00",
"updated_at": "2026-10-02T09:13:04+00:00",
"flow_execution": {
"execution_id": "74442180941398016",
"flow_id": "74438623450128384",
"node_key": "model"
}
}
}Отримати холди однієї операції
Запит лишає холди generate_email за останні сім днів, по двадцять на сторінку.
curl "https://api.slen.ai/api/v1/authorizations?operation_code=generate_email&limit=20" \
-H "Authorization: Bearer $SLEN_API_KEY"Що читати далі
Надіслати запит — той самий запит із SDK і кожне поле його відповіді.
Ідемпотентність — чим відповідають на повтор запиту до флоу.
Асинхронні запуски й очікування — прочитати виконання, яке відповіло
202.Записи реєстру — гроші, які кожен виклик зарезервував і списав.
Як працює резервування бюджету — що холд робить із бюджетом і чим він закінчується.
AI-флоу — як код операції прив’язують до флоу.
Виконання — статус і трасування виконання, яке відкрив запит.
Зібрано з openapi b070e1f, sdk contract 5cc7055, php ae4a53b, node 84bc62d