DevelopersAPI reference

API reference

Every /v1 route, built from the OpenAPI document the API serves. New to the API? Start with the guide.

Base URL
https://api.smiletoai.com
Auth header
Bearer stai_live_…
Version
1.0.0, OpenAPI 3.1
Download
openapi.json

Account

Who you are calling as.

GET/v1/me

The team and key behind this request

Check that a key works and see the team, plan, scopes and rate limit it carries, its monthly Sparks cap and what it spent this month, and the Sparks the team can spend.

ScopereadReturns200

Response 200

  • teamobjectrequired

    The team the key belongs to.

  • team.idstringrequired

    The team's id.

  • team.namestringrequired

    The team's name.

  • team.planstringrequired

    The team's plan, e.g. plus, pro or team.

  • api_keyobjectrequired

    The key that made this request.

  • api_key.idstringrequired

    The key's id.

  • api_key.namestringrequired

    The name given to the key in Settings.

  • api_key.prefixstringrequired

    The 8-character prefix shown in Settings.

  • api_key.scopesarray of stringsrequired

    Any of read, run and webhooks.

  • api_key.rate_limit_per_minuteintegerrequired

    Requests per minute this key may make.

  • api_key.monthly_sparks_capintegerrequired

    The most this key's runs may hold or be charged in one UTC calendar month, or null for no cap. Set in Settings > API keys.

  • api_key.sparks_this_monthintegerrequired

    Sparks this key's runs started this UTC month hold or were charged, checked against the cap.

  • api_key.month_resets_atstringrequired

    When sparks_this_month starts again from zero: the start of the next UTC month (ISO 8601).

  • sparks_availableintegerrequired

    Sparks the team can spend right now.

Errors use one shape across the API. See the error codes

curl https://api.smiletoai.com/v1/me \
  -H "Authorization: Bearer $SMILETOAI_KEY"
200ResponseExample
{
  "object": "me",
  "team": {
    "id": "6f0c2d9a-3b1e-4f57-9a0d-2c8e5b7f1a64",
    "name": "Northwind Studio",
    "plan": "pro"
  },
  "api_key": {
    "id": "a3e1b0c4-5d2f-4e8a-b7c9-0f1e2d3c4b5a",
    "name": "Production",
    "prefix": "k7m2p9qa",
    "scopes": [
      "read",
      "run"
    ],
    "rate_limit_per_minute": 60,
    "monthly_sparks_cap": 20000,
    "sparks_this_month": 4120,
    "month_resets_at": "2026-11-01T00:00:00Z"
  },
  "sparks_available": 84210
}

Tools

What you can run, what it costs, and starting a run.

GET/v1/tools

List the tools this key can run

Tools available over the API, with their input slots and a typical price range. allowed is false when the team's plan does not include a tool.

ScopereadReturns200

Response 200

  • dataarray of objectsrequired

    Tools available over the API that this key can see.

  • data[].idstringrequired

    The tool id used in /v1/tools/{tool_id}/estimate and /runs, e.g. image_upscale.

  • data[].namestringrequired

    The tool's display name.

  • data[].descriptionstringrequired

    What the tool does.

  • data[].familystringrequired

    The tool's group, e.g. enhance, edit or analyze.

  • data[].inputsarray of objectsrequired

    The input slots a run takes.

  • data[].output_kindstringrequired

    What a run produces: image, video, audio or json.

  • data[].consentstringrequired

    none, voice or face. Identity tools need an element with active consent.

  • data[].allowedbooleanrequired

    False when the team's plan does not include this tool.

  • data[].estimate_hintobjectrequired

    A typical price range. Estimate a run for its exact price.

Errors use one shape across the API. See the error codes

curl https://api.smiletoai.com/v1/tools \
  -H "Authorization: Bearer $SMILETOAI_KEY"
200ResponseExample
{
  "object": "list",
  "data": [
    {
      "object": "tool",
      "id": "image_upscale",
      "name": "Upscale image",
      "description": "Upscale image enlarges and sharpens an image with an AI super-resolution model (up to 4096 px on the long side).",
      "family": "enhance",
      "inputs": [
        {
          "name": "image",
          "kind": "image",
          "required": true,
          "min": 1,
          "max": 1,
          "constraints": {
            "max_pixels": 16000000,
            "mime_types": [
              "image/png",
              "image/jpeg",
              "image/webp"
            ]
          },
          "choices": null,
          "default": null
        }
      ],
      "output_kind": "image",
      "consent": "none",
      "allowed": true,
      "estimate_hint": {
        "sparks_min": 30,
        "sparks_max": 30
      }
    }
  ]
}
POST/v1/tools/{tool_id}/estimate

Price a run without starting it

Prices the exact inputs you will send. It starts nothing and spends nothing. Video tools take duration_seconds when the length is not known from a file yet.

ScopereadReturns200

Parameters

  • tool_idpath · stringrequired

    A tool id from GET /v1/tools, such as image_upscale.

Body

  • inputsobject

    Slot name to value; media slots take a list of file ids.

  • duration_secondsnumber

    Length hint for metered video tools before the file is resolved.

Response 200

  • tool_idstringrequired

    The tool that was priced.

  • product_idstringrequired

    The product the tool runs on.

  • sparksintegerrequired

    What the run is expected to cost.

  • reserve_sparksintegerrequired

    What the run holds from the balance while it runs; unused Sparks are refunded.

Errors use one shape across the API. See the error codes

curl -X POST https://api.smiletoai.com/v1/tools/image_upscale/estimate \
  -H "Authorization: Bearer $SMILETOAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"inputs": {"image": ["9d41e2c7-0b8a-4f3e-a1d5-6c7b8e9f0a12"]}}'
200ResponseExample
{
  "object": "estimate",
  "tool_id": "image_upscale",
  "product_id": "image_upscale",
  "sparks": 30,
  "reserve_sparks": 30
}
POST/v1/tools/{tool_id}/runs

Start a run (it spends the team's Sparks)

Holds the estimated Sparks, queues the run and answers 202 with it. Repeating an Idempotency-Key returns the run it already started instead of a new one. Read the run with GET /v1/runs/{run_id}, or receive a webhook when it ends.

ScoperunReturns202

Parameters

  • tool_idpath · stringrequired

    A tool id from GET /v1/tools, such as image_upscale.

  • Idempotency-Keyheader · string

    Any string up to 255 characters. Sending the same key again returns the run it already started.

Body

  • inputsobject

    Slot name to value; media slots take a list of file ids.

  • duration_secondsnumber

    Length hint for metered video tools before the file is resolved.

Response 202

  • idstringrequired

    The run id, for GET /v1/runs/{run_id}.

  • tool_idstringrequired

    The tool that runs.

  • product_idstringrequired

    The product the tool runs on.

  • status"queued" | "running" | "succeeded" | "failed" | "canceled"required

    succeeded, failed and canceled are final; poll until you see one of them.

  • progressnumberrequired

    From 0 to 1 while the run works.

  • cost_sparksintegerrequired

    The hold while the run is in flight; what was charged once it is terminal.

  • outputsarray of objectsrequired

    The files a succeeded run produced; empty until then.

  • outputs[].asset_idstringrequired

    Pass it to /v1/runs/{run_id}/outputs/{asset_id}/url to download the file.

  • outputs[].mime_typestring

    The file's media type, e.g. image/png.

  • outputs[].widthinteger

    Pixel width of an image or video.

  • outputs[].heightinteger

    Pixel height of an image or video.

  • outputs[].duration_secondsnumber

    Length of a video or audio file.

  • outputs[].size_bytesinteger

    File size in bytes.

  • outputs[].file_namestring

    A suggested file name.

  • errorstringrequired

    Why a failed run failed.

  • api_key_idstringrequired

    The API key that started the run.

  • created_atstringrequired

    When the run was started (ISO 8601, UTC).

  • started_atstringrequired

    When work began (ISO 8601, UTC).

  • finished_atstringrequired

    When the run reached a final status (ISO 8601, UTC).

Errors use one shape across the API. See the error codes

curl -X POST https://api.smiletoai.com/v1/tools/image_upscale/runs \
  -H "Authorization: Bearer $SMILETOAI_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042" \
  -d '{"inputs": {"image": ["9d41e2c7-0b8a-4f3e-a1d5-6c7b8e9f0a12"]}}'
202ResponseExample
{
  "object": "run",
  "id": "8f2c0b7e-41d6-4c1a-9e55-2b7d1f0c9a31",
  "tool_id": "image_upscale",
  "product_id": "image_upscale",
  "status": "queued",
  "progress": 0,
  "cost_sparks": 30,
  "outputs": [],
  "error": null,
  "api_key_id": "a3e1b0c4-5d2f-4e8a-b7c9-0f1e2d3c4b5a",
  "created_at": "2026-10-17T09:12:03Z",
  "started_at": null,
  "finished_at": null
}

Runs

Reading, canceling and downloading the runs your keys started.

GET/v1/runs

List runs

Runs started with any of this team's API keys (and MCP connections), newest first. Pass next_cursor as cursor to read the next page; filter by status (repeatable), tool_id, api_key_id and a created_at window.

ScopereadReturns200

Parameters

  • limitquery · integer

    Runs per page.

  • cursorquery · string

    next_cursor from the previous page.

  • statusquery · array of "queued" | "running" | "succeeded" | "failed" | "canceled"

    Only runs in these statuses; repeat the parameter for several.

  • tool_idquery · string

    Only runs of this tool, such as image_upscale.

  • api_key_idquery · string

    Only runs started with this key.

  • created_afterquery · string

    Only runs started at or after this time (ISO 8601; UTC if no offset).

  • created_beforequery · string

    Only runs started before this time (ISO 8601; UTC if no offset).

Response 200

  • dataarray of objectsrequired

    Runs, newest first.

  • data[].idstringrequired

    The run id, for GET /v1/runs/{run_id}.

  • data[].tool_idstringrequired

    The tool that runs.

  • data[].product_idstringrequired

    The product the tool runs on.

  • data[].status"queued" | "running" | "succeeded" | "failed" | "canceled"required

    succeeded, failed and canceled are final; poll until you see one of them.

  • data[].progressnumberrequired

    From 0 to 1 while the run works.

  • data[].cost_sparksintegerrequired

    The hold while the run is in flight; what was charged once it is terminal.

  • data[].outputsarray of objectsrequired

    The files a succeeded run produced; empty until then.

  • data[].errorstringrequired

    Why a failed run failed.

  • data[].api_key_idstringrequired

    The API key that started the run.

  • data[].created_atstringrequired

    When the run was started (ISO 8601, UTC).

  • data[].started_atstringrequired

    When work began (ISO 8601, UTC).

  • data[].finished_atstringrequired

    When the run reached a final status (ISO 8601, UTC).

  • has_morebooleanrequired

    Whether another page follows; pass next_cursor as cursor to read it.

  • next_cursorstringrequired

    The cursor for the next page, or null on the last one.

Errors use one shape across the API. See the error codes

curl https://api.smiletoai.com/v1/runs \
  -H "Authorization: Bearer $SMILETOAI_KEY"
200ResponseExample
{
  "object": "list",
  "data": [
    {
      "object": "run",
      "id": "8f2c0b7e-41d6-4c1a-9e55-2b7d1f0c9a31",
      "tool_id": "image_upscale",
      "product_id": "image_upscale",
      "status": "succeeded",
      "progress": 1,
      "cost_sparks": 30,
      "outputs": [
        {
          "asset_id": "c71a5e02-9b4d-4e1f-8a3c-5d6e7f8091a2",
          "mime_type": "image/png",
          "width": 4096,
          "height": 4096,
          "duration_seconds": null,
          "size_bytes": 9420117,
          "file_name": "photo-upscaled.png"
        }
      ],
      "error": null,
      "api_key_id": "a3e1b0c4-5d2f-4e8a-b7c9-0f1e2d3c4b5a",
      "created_at": "2026-10-17T09:12:03Z",
      "started_at": "2026-10-17T09:12:05Z",
      "finished_at": "2026-10-17T09:12:41Z"
    }
  ],
  "has_more": true,
  "next_cursor": "WyIyMDI2LTEwLTE3VDA5OjEyOjAwWiIsIjVmM2E5YzJlIl0"
}
GET/v1/runs/{run_id}

Get a run

Only runs started with this team's API keys. Poll every 2 to 5 seconds until the status is succeeded, failed or canceled.

ScopereadReturns200

Parameters

  • run_idpath · stringrequired

    The id of a run started with one of your team's API keys.

Response 200

  • idstringrequired

    The run id, for GET /v1/runs/{run_id}.

  • tool_idstringrequired

    The tool that runs.

  • product_idstringrequired

    The product the tool runs on.

  • status"queued" | "running" | "succeeded" | "failed" | "canceled"required

    succeeded, failed and canceled are final; poll until you see one of them.

  • progressnumberrequired

    From 0 to 1 while the run works.

  • cost_sparksintegerrequired

    The hold while the run is in flight; what was charged once it is terminal.

  • outputsarray of objectsrequired

    The files a succeeded run produced; empty until then.

  • outputs[].asset_idstringrequired

    Pass it to /v1/runs/{run_id}/outputs/{asset_id}/url to download the file.

  • outputs[].mime_typestring

    The file's media type, e.g. image/png.

  • outputs[].widthinteger

    Pixel width of an image or video.

  • outputs[].heightinteger

    Pixel height of an image or video.

  • outputs[].duration_secondsnumber

    Length of a video or audio file.

  • outputs[].size_bytesinteger

    File size in bytes.

  • outputs[].file_namestring

    A suggested file name.

  • errorstringrequired

    Why a failed run failed.

  • api_key_idstringrequired

    The API key that started the run.

  • created_atstringrequired

    When the run was started (ISO 8601, UTC).

  • started_atstringrequired

    When work began (ISO 8601, UTC).

  • finished_atstringrequired

    When the run reached a final status (ISO 8601, UTC).

Errors use one shape across the API. See the error codes

curl https://api.smiletoai.com/v1/runs/8f2c0b7e-41d6-4c1a-9e55-2b7d1f0c9a31 \
  -H "Authorization: Bearer $SMILETOAI_KEY"
200ResponseExample
{
  "object": "run",
  "id": "8f2c0b7e-41d6-4c1a-9e55-2b7d1f0c9a31",
  "tool_id": "image_upscale",
  "product_id": "image_upscale",
  "status": "succeeded",
  "progress": 1,
  "cost_sparks": 30,
  "outputs": [
    {
      "asset_id": "c71a5e02-9b4d-4e1f-8a3c-5d6e7f8091a2",
      "mime_type": "image/png",
      "width": 4096,
      "height": 4096,
      "duration_seconds": null,
      "size_bytes": 9420117,
      "file_name": "photo-upscaled.png"
    }
  ],
  "error": null,
  "api_key_id": "a3e1b0c4-5d2f-4e8a-b7c9-0f1e2d3c4b5a",
  "created_at": "2026-10-17T09:12:03Z",
  "started_at": "2026-10-17T09:12:05Z",
  "finished_at": "2026-10-17T09:12:41Z"
}
POST/v1/runs/{run_id}/cancel

Cancel a queued or running run

Stops the run and releases its hold, as canceling in the app does.

ScoperunReturns200

Parameters

  • run_idpath · stringrequired

    The id of a run started with one of your team's API keys.

Response 200

  • idstringrequired

    The run id, for GET /v1/runs/{run_id}.

  • tool_idstringrequired

    The tool that runs.

  • product_idstringrequired

    The product the tool runs on.

  • status"queued" | "running" | "succeeded" | "failed" | "canceled"required

    succeeded, failed and canceled are final; poll until you see one of them.

  • progressnumberrequired

    From 0 to 1 while the run works.

  • cost_sparksintegerrequired

    The hold while the run is in flight; what was charged once it is terminal.

  • outputsarray of objectsrequired

    The files a succeeded run produced; empty until then.

  • outputs[].asset_idstringrequired

    Pass it to /v1/runs/{run_id}/outputs/{asset_id}/url to download the file.

  • outputs[].mime_typestring

    The file's media type, e.g. image/png.

  • outputs[].widthinteger

    Pixel width of an image or video.

  • outputs[].heightinteger

    Pixel height of an image or video.

  • outputs[].duration_secondsnumber

    Length of a video or audio file.

  • outputs[].size_bytesinteger

    File size in bytes.

  • outputs[].file_namestring

    A suggested file name.

  • errorstringrequired

    Why a failed run failed.

  • api_key_idstringrequired

    The API key that started the run.

  • created_atstringrequired

    When the run was started (ISO 8601, UTC).

  • started_atstringrequired

    When work began (ISO 8601, UTC).

  • finished_atstringrequired

    When the run reached a final status (ISO 8601, UTC).

Errors use one shape across the API. See the error codes

curl -X POST https://api.smiletoai.com/v1/runs/8f2c0b7e-41d6-4c1a-9e55-2b7d1f0c9a31/cancel \
  -H "Authorization: Bearer $SMILETOAI_KEY"
200ResponseExample
{
  "object": "run",
  "id": "8f2c0b7e-41d6-4c1a-9e55-2b7d1f0c9a31",
  "tool_id": "image_upscale",
  "product_id": "image_upscale",
  "status": "canceled",
  "progress": 0,
  "cost_sparks": 0,
  "outputs": [],
  "error": null,
  "api_key_id": "a3e1b0c4-5d2f-4e8a-b7c9-0f1e2d3c4b5a",
  "created_at": "2026-10-17T09:12:03Z",
  "started_at": null,
  "finished_at": "2026-10-17T09:12:09Z"
}
GET/v1/runs/{run_id}/outputs/{asset_id}/url

Get a short-lived download URL for an output

A signed URL for one output of a succeeded run. Download straight away and ask again when it expires. 409 output_not_ready means the file is still being checked.

ScopereadReturns200

Parameters

  • run_idpath · stringrequired

    The id of a run started with one of your team's API keys.

  • asset_idpath · stringrequired

    An asset_id from the run's outputs.

Response 200

  • asset_idstringrequired

    The output this URL downloads.

  • urlstringrequired

    A signed download URL. Fetch it straight away.

  • expires_in_secondsintegerrequired

    How long the URL works. Ask again for a fresh one after that.

Errors use one shape across the API. See the error codes

curl https://api.smiletoai.com/v1/runs/8f2c0b7e-41d6-4c1a-9e55-2b7d1f0c9a31/outputs/c71a5e02-9b4d-4e1f-8a3c-5d6e7f8091a2/url \
  -H "Authorization: Bearer $SMILETOAI_KEY"
200ResponseExample
{
  "object": "output_url",
  "asset_id": "c71a5e02-9b4d-4e1f-8a3c-5d6e7f8091a2",
  "url": "https://storage.example.com/c71a5e02-9b4d-4e1f-8a3c-5d6e7f8091a2.png?signature=…",
  "expires_in_seconds": 600
}

Files

Uploading the files media inputs take.

POST/v1/files/upload-url

Start a file upload

Creates a file and returns one presigned URL per part. PUT each part to its URL, keep each ETag response header, then call POST /v1/files/{file_id}/complete.

ScoperunReturns201

Body

  • file_namestringrequired

    The file's name, e.g. photo.png.

  • mime_typestringrequired

    The file's media type, e.g. image/png.

  • size_bytesintegerrequired

    The exact size of the file in bytes.

Response 201

  • file_idstringrequired

    The file's id. Media inputs take it once the upload is complete.

  • upload_idstringrequired

    Send it back to /v1/files/{file_id}/complete.

  • part_size_bytesintegerrequired

    Bytes per part; the last part may be smaller.

  • partsarray of objectsrequired

    PUT each byte range to its URL, keep each response's ETag, then complete.

  • parts[].part_numberintegerrequired

    The part's position, from 1.

  • parts[].urlstringrequired

    A presigned URL. PUT this part's bytes to it and keep the ETag response header.

  • expires_in_secondsintegerrequired

    How long the part URLs work.

Errors use one shape across the API. See the error codes

curl -X POST https://api.smiletoai.com/v1/files/upload-url \
  -H "Authorization: Bearer $SMILETOAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_name": "photo.png", "mime_type": "image/png", "size_bytes": 482113}'
201ResponseExample
{
  "object": "file_upload",
  "file_id": "9d41e2c7-0b8a-4f3e-a1d5-6c7b8e9f0a12",
  "upload_id": "cGhvdG8tdXBsb2FkLTE",
  "part_size_bytes": 8388608,
  "parts": [
    {
      "part_number": 1,
      "url": "https://storage.example.com/uploads/photo.png?partNumber=1&signature=…"
    }
  ],
  "expires_in_seconds": 900
}
POST/v1/files/{file_id}/complete

Finish a file upload

Completes the upload with every part's ETag. The file id then works in media inputs.

ScoperunReturns200

Parameters

  • file_idpath · stringrequired

    The file_id from POST /v1/files/upload-url.

Body

  • upload_idstringrequired

    The upload_id from /v1/files/upload-url.

  • partsarray of objectsrequired

    Every part you uploaded.

  • parts[].part_numberintegerrequired

    The part's position, as in the upload response.

  • parts[].etagstringrequired

    The ETag header returned by that part's PUT.

Response 200

  • idstringrequired

    The file id to use in media inputs.

  • statusstringrequired

    The file's state after completion.

Errors use one shape across the API. See the error codes

curl -X POST https://api.smiletoai.com/v1/files/9d41e2c7-0b8a-4f3e-a1d5-6c7b8e9f0a12/complete \
  -H "Authorization: Bearer $SMILETOAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"upload_id": "cGhvdG8tdXBsb2FkLTE", "parts": [{"part_number": 1, "etag": "\"5d41402abc4b2a76b9719d911017c592\""}]}'
200ResponseExample
{
  "object": "file",
  "id": "9d41e2c7-0b8a-4f3e-a1d5-6c7b8e9f0a12",
  "status": "uploaded"
}

Webhooks

Managing the endpoints that receive run events.

GET/v1/webhook-endpoints

List webhook endpoints

The team's endpoints. The key's creator must be a team owner or admin.

ScopewebhooksReturns200

Response 200

  • dataarray of objectsrequired

    The team's webhook endpoints.

  • data[].idstringrequired

    The endpoint's id.

  • data[].urlstringrequired

    Where deliveries are POSTed.

  • data[].eventsarray of stringsrequired

    Any of run.succeeded, run.failed and run.canceled.

  • data[].enabledbooleanrequired

    A paused endpoint receives nothing, and runs that finish while it is paused are not sent later.

  • data[].created_atstringrequired

    When the endpoint was added (ISO 8601, UTC).

Errors use one shape across the API. See the error codes

curl https://api.smiletoai.com/v1/webhook-endpoints \
  -H "Authorization: Bearer $SMILETOAI_KEY"
200ResponseExample
{
  "object": "list",
  "data": [
    {
      "object": "webhook_endpoint",
      "id": "4b8e2f10-7c3d-4a9e-b5f6-1d2c3e4f5a6b",
      "url": "https://example.com/hooks/smiletoai",
      "events": [
        "run.succeeded",
        "run.failed",
        "run.canceled"
      ],
      "enabled": true,
      "created_at": "2026-10-17T08:40:00Z"
    }
  ]
}
POST/v1/webhook-endpoints

Add a webhook endpoint

Adds an HTTPS endpoint (up to 10 per team) and returns its signing secret once. It receives the runs that finish from now on; nothing earlier is replayed.

ScopewebhooksReturns201

Body

  • urlstringrequired

    An HTTPS URL on a public host.

  • eventsarray of strings

    Any of run.succeeded, run.failed, run.canceled; all three when omitted.

Response 201

  • idstringrequired

    The endpoint's id.

  • urlstringrequired

    Where deliveries are POSTed.

  • eventsarray of stringsrequired

    Any of run.succeeded, run.failed and run.canceled.

  • enabledbooleanrequired

    A paused endpoint receives nothing, and runs that finish while it is paused are not sent later.

  • created_atstringrequired

    When the endpoint was added (ISO 8601, UTC).

  • signing_secretstringrequired

    Shown once. Verify SmileToAI-Signature with it.

Errors use one shape across the API. See the error codes

curl -X POST https://api.smiletoai.com/v1/webhook-endpoints \
  -H "Authorization: Bearer $SMILETOAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/hooks/smiletoai", "events": ["run.succeeded", "run.failed"]}'
201ResponseExample
{
  "object": "webhook_endpoint",
  "id": "4b8e2f10-7c3d-4a9e-b5f6-1d2c3e4f5a6b",
  "url": "https://example.com/hooks/smiletoai",
  "events": [
    "run.succeeded",
    "run.failed"
  ],
  "enabled": true,
  "created_at": "2026-10-17T08:40:00Z",
  "signing_secret": "whsec_…"
}
PATCH/v1/webhook-endpoints/{endpoint_id}

Pause, resume or change events

Pausing drops the endpoint's pending deliveries. A resumed endpoint receives the runs that finish after it is resumed; runs that finished while it was paused are not sent.

ScopewebhooksReturns200

Parameters

  • endpoint_idpath · stringrequired

    A webhook endpoint id.

Body

  • enabledboolean

    false pauses the endpoint and drops its pending deliveries; true resumes it.

  • eventsarray of strings

    Replaces the endpoint's events.

Response 200

  • idstringrequired

    The endpoint's id.

  • urlstringrequired

    Where deliveries are POSTed.

  • eventsarray of stringsrequired

    Any of run.succeeded, run.failed and run.canceled.

  • enabledbooleanrequired

    A paused endpoint receives nothing, and runs that finish while it is paused are not sent later.

  • created_atstringrequired

    When the endpoint was added (ISO 8601, UTC).

Errors use one shape across the API. See the error codes

curl -X PATCH https://api.smiletoai.com/v1/webhook-endpoints/4b8e2f10-7c3d-4a9e-b5f6-1d2c3e4f5a6b \
  -H "Authorization: Bearer $SMILETOAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'
200ResponseExample
{
  "object": "webhook_endpoint",
  "id": "4b8e2f10-7c3d-4a9e-b5f6-1d2c3e4f5a6b",
  "url": "https://example.com/hooks/smiletoai",
  "events": [
    "run.succeeded",
    "run.failed",
    "run.canceled"
  ],
  "enabled": false,
  "created_at": "2026-10-17T08:40:00Z"
}
DELETE/v1/webhook-endpoints/{endpoint_id}

Delete a webhook endpoint

Removes the endpoint. Deliveries to it stop.

ScopewebhooksReturns200

Parameters

  • endpoint_idpath · stringrequired

    A webhook endpoint id.

Response 200

  • idstringrequired

    The id of what was deleted.

  • deletedboolean

Errors use one shape across the API. See the error codes

curl -X DELETE https://api.smiletoai.com/v1/webhook-endpoints/4b8e2f10-7c3d-4a9e-b5f6-1d2c3e4f5a6b \
  -H "Authorization: Bearer $SMILETOAI_KEY"
200ResponseExample
{
  "object": "deleted",
  "id": "4b8e2f10-7c3d-4a9e-b5f6-1d2c3e4f5a6b",
  "deleted": true
}
POST/v1/webhook-endpoints/{endpoint_id}/test

Send a signed ping now

Sends a signed ping event to the endpoint and reports how it answered.

ScopewebhooksReturns200

Parameters

  • endpoint_idpath · stringrequired

    A webhook endpoint id.

Response 200

  • delivery_idstringrequired

    The SmileToAI-Delivery header of the ping.

  • deliveredbooleanrequired

    Whether your endpoint answered with a 2xx.

  • response_codeintegerrequired

    The HTTP status your endpoint answered with.

  • duration_msintegerrequired

    How long the delivery took.

  • errorstringrequired

    Why the delivery failed, if it did.

Errors use one shape across the API. See the error codes

curl -X POST https://api.smiletoai.com/v1/webhook-endpoints/4b8e2f10-7c3d-4a9e-b5f6-1d2c3e4f5a6b/test \
  -H "Authorization: Bearer $SMILETOAI_KEY"
200ResponseExample
{
  "object": "webhook_test",
  "delivery_id": "2b9e47d1-6a5c-4f8b-9e0d-3c2b1a0f9e8d",
  "delivered": true,
  "response_code": 200,
  "duration_ms": 182,
  "error": null
}