> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.sailorhq.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.sailorhq.io/_mcp/server.

# Troubleshooting

> Diagnose common phone-system API and webhook issues.

Start from the symptom you see. Sailor returns RFC 9457 `application/problem+json` with a stable `code` and `request_id`, so your backend can log the exact failure and choose the next action.

Pick the card that matches the failure mode, then work through the checks in that section.

## Start Here

#### [Request was rejected](#request-was-rejected)

The API returned `unauthorized`, `insufficient_scope`, or `feature_not_available`.

#### [Outcome did not save](#outcome-did-not-save)

Create or update returned `invalid_outcome` or `destination_not_found`.

#### [Webhook did not arrive](#webhook-did-not-arrive)

An action outcome was applied, but your endpoint did not receive a payload.

#### [Post-call workflow did not appear](#post-call-workflow-did-not-appear)

Agents are not seeing a required disposition step after calls.

## Request Was Rejected

| Error                     | Meaning                                                               | Fix                                                           |
| ------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------- |
| `unauthorized`            | The request could not be authenticated.                               | Check the `Authorization` header and token value.             |
| `insufficient_scope`      | The key is valid, but not allowed to perform this action.             | Create or rotate a key with the operation's documented scope. |
| `feature_not_available`   | Phone-system outcomes are not enabled for the key's workspace.        | Enable the feature in that same workspace.                    |
| `rate_limit_exceeded`     | Credential or workspace cost units are exhausted.                     | Wait for `Retry-After`; inspect the RateLimit headers.        |
| `temporarily_unavailable` | A safe shared control could not complete or concurrency is saturated. | Retry idempotently after `Retry-After`.                       |

## Outcome Did Not Save

| Error                     | Likely cause                                                  | Fix                                                                     |
| ------------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `missing_idempotency_key` | A create or update request omitted a valid `Idempotency-Key`. | Add an 8–255 character stable key for the logical operation.            |
| `request_in_progress`     | The same idempotency key and request are already processing.  | Wait for `Retry-After`, then retry the exact request with the same key. |
| `idempotency_key_reused`  | The key was reused with different request data.               | Use a new key for the new logical operation.                            |
| `invalid_request`         | The path or request body failed validation.                   | Check the generated endpoint schema.                                    |
| `resource_not_found`      | The outcome or destination is not present in this workspace.  | List resources using the same key and retry with a returned ID.         |

## Webhook Did Not Arrive

Check these in order:

#### Confirm the outcome is an action

Webhooks are sent for action outcomes with a configured `webhook_url`.

#### Confirm the URL is public HTTPS

Localhost and private network URLs cannot receive Sailor webhooks. Use a tunnel for local testing.

#### Confirm your server returns 2xx

Return a `2xx` status after accepting the payload. Move slow work into a queue.

#### Check your receiver logs

Log request method, path, status, and body while testing.

## Post-Call Workflow Did Not Appear

`disposition_popup_enabled` is `true` only when at least one outcome has `outcome_type: "disposition"`.

If agents do not see a post-call disposition step:

1. Call `GET /phone-system/outcomes`.
2. Confirm at least one returned outcome has `outcome_type: "disposition"`.
3. Confirm the agent is using the same workspace as the API token.
4. Create a disposition outcome if none exists.

## Smart List Movement Did Not Match Expectation

| What happened                      | What to check                                                                                      |
| ---------------------------------- | -------------------------------------------------------------------------------------------------- |
| Person was not added to a list.    | The outcome should use `destination_type: "smart_list"` and a valid `destination_id`.              |
| Person was not removed from lists. | The outcome should use `destination_type: "remove_from_smart_list"` and `remove_from_smart_lists`. |
| Only some lists changed.           | For selected removal, confirm every list ID is present in `remove_from_smart_lists.list_ids`.      |

## Still Stuck

Capture the method, path, request body, response body, and approximate time of the request. If the issue involves a webhook, include your receiver logs and the outcome ID.