> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stairoids.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting Stairoids Integrations and Signals

> Diagnose and resolve common issues with signal delivery, API authentication, outgoing automations, and engagement score updates in Stairoids.

When something isn't working as expected in Stairoids, the **Signal Activity Log** is your first stop. Navigate to **Settings → Logs** to see a real-time stream of every inbound signal, outbound automation execution, and webhook delivery in your workspace — including their status (`success`, `failed`, `retrying`) and any associated error messages. Most issues can be diagnosed in under a minute by filtering the log by the relevant signal ID, account domain, or time window.

<Tip>
  Every API response body — including error responses — includes a `request_id` field. Make a note of this value whenever you encounter an unexpected result. Stairoids support can use it to look up the exact request when investigating your issue. Always include it in your support ticket.
</Tip>

***

## Signals Not Arriving

If signals from a connected source are not appearing in Stairoids, work through the following checks in order.

<AccordionGroup>
  <Accordion title="Verify the integration is enabled">
    Navigate to **Settings → Integrations** and locate the relevant integration (e.g., Segment, HubSpot, or your custom API source). Confirm that its status toggle shows **Enabled** (green). If it's disabled, click the toggle to re-enable it — new signals begin flowing immediately.

    Also confirm that the integration is configured to send the event types you're expecting. Some integrations have event-type filters that can silently drop certain signal categories.
  </Accordion>

  <Accordion title="Check that the API key is valid and has write scope">
    If you're ingesting signals via the REST API, your API key must be a **Read-Write** key. A Read-only key returns a `403 Forbidden` error when you attempt to create a signal, and the signal will not be recorded.

    To verify: go to **Settings → API Keys** and confirm the key you're using shows **Read-Write** in the Scope column. If it shows **Read-only**, generate a new Read-Write key and update your integration. See [Rotating Keys](/configuration/authentication#rotating-keys) for a zero-downtime procedure.
  </Accordion>

  <Accordion title="Confirm the source tool is sending to the correct URL">
    For incoming webhook integrations, check that the source tool is configured with the exact webhook URL shown in **Settings → Automations → Incoming**. A missing trailing slash, a typo in the path, or an outdated URL from a previous setup can silently drop all incoming traffic.

    Use your source tool's delivery log (most platforms like Zapier, Segment, and HubSpot show per-event delivery status) to confirm the request is being sent and what HTTP status code the endpoint is returning.
  </Accordion>

  <Accordion title="Check the Activity Log for errors">
    Open **Settings → Logs** and filter by the time window when you expected signals to arrive. Look for entries with a `failed` status and expand them to see the full error message. Common errors include:

    * **`invalid_payload`**: The signal body is missing a required field. The error message will specify which field. The most common culprits are a missing `type`, `account.domain`, or `contact.email`.
    * **`domain_excluded`**: The domain in the signal matches an entry in your Excluded Domains list under **Settings → Account Matching**. Remove the domain from the exclusion list if this is unintended.
    * **`rate_limit_exceeded`**: Your API key has hit its per-minute request limit. Implement backoff and retry logic in your integration.
  </Accordion>
</AccordionGroup>

***

## Outgoing Automation Not Firing

If a configured automation isn't triggering when you expect it to, step through these checks before raising a support ticket.

<AccordionGroup>
  <Accordion title="Verify trigger conditions using Simulate">
    Open the automation editor and click **Simulate** in the top toolbar. Paste a sample signal JSON payload and run the simulation — Stairoids evaluates the automation's trigger conditions against your sample and shows you exactly which conditions passed, which failed, and why.

    Common trigger condition mistakes include using the wrong signal type name (e.g., `pageview` instead of `page_view`), referencing a property key with the wrong casing, or setting a score threshold higher than any account in your workspace currently achieves.
  </Accordion>

  <Accordion title="Check that the destination integration is connected and authorized">
    Navigate to **Settings → Integrations** and click on the destination integration the automation writes to (e.g., Slack, HubSpot CRM, Salesforce). Verify its connection status shows **Connected**. If it shows **Reconnection Required**, the OAuth token or API credentials have expired — click **Reconnect** and re-authorize the integration.

    OAuth tokens for many CRMs and communication tools expire after 60–90 days of inactivity. Reconnecting takes under a minute and does not affect historical data.
  </Accordion>

  <Accordion title="Ensure the automation is enabled">
    In the Automations list (**Automations → Outgoing**), check that the automation's status toggle is **green (enabled)**. A disabled automation does not evaluate triggers or execute actions — it silently skips all matching signals. Click the toggle to re-enable it.

    Also confirm the automation hasn't been accidentally paused. A paused automation shows a yellow **Paused** badge and can be resumed from the automation detail page.
  </Accordion>

  <Accordion title="Review execution history in the Activity Log">
    Go to **Settings → Logs** and filter by the automation name or ID. If the automation triggered but the destination action failed, you'll see a `failed` entry with a detailed error from the downstream API (e.g., a missing required CRM field, an invalid Slack channel ID, or a payload validation error). Fix the underlying issue and use the **Retry** button to re-run the failed execution against the same signal.
  </Accordion>
</AccordionGroup>

***

## API Errors

<AccordionGroup>
  <Accordion title="401 Unauthorized — missing or invalid API key">
    A `401` response means the `Authorization` header is missing, the key value is malformed, or the key has been revoked.

    **Steps to resolve:**

    1. Confirm your request includes the header: `Authorization: Bearer <your-api-key>`
    2. Go to **Settings → API Keys** and verify the key appears in the list and is not marked as revoked.
    3. If the key is missing or revoked, generate a new one, update your integration, and test again.
    4. Check that you haven't accidentally included extra whitespace, newlines, or quotes around the key value when reading it from an environment variable.
  </Accordion>

  <Accordion title="422 Unprocessable Entity — invalid request payload">
    A `422` response means the API received your request but the payload failed validation. The response body contains a `details` array that lists every validation error and the specific field that caused it.

    ```json theme={null}
    {
      "error": "unprocessable_entity",
      "message": "Request payload failed validation.",
      "details": [
        { "field": "type", "message": "type is required" },
        { "field": "account.domain", "message": "account.domain must be a valid domain name" }
      ],
      "request_id": "req_01HXYZ9999AABBCC"
    }
    ```

    The most common causes are:

    * Missing `type` field on a signal creation request.
    * Missing both `account.domain` and `contact.email` — at least one is required to attribute a signal to an account or contact.
    * Providing an `account.domain` value that includes a protocol prefix (e.g., `https://acme.com` instead of `acme.com`).
    * Sending a `created_at` timestamp in a format other than ISO 8601 UTC.
  </Accordion>

  <Accordion title="429 Too Many Requests — rate limit exceeded">
    A `429` response means your API key has exceeded its allowed request rate. The response includes two headers to help you back off correctly:

    * `Retry-After`: The number of seconds to wait before making another request.
    * `X-RateLimit-Reset`: The Unix timestamp at which your rate limit window resets.

    ```http theme={null}
    HTTP/1.1 429 Too Many Requests
    Retry-After: 18
    X-RateLimit-Limit: 60
    X-RateLimit-Remaining: 0
    X-RateLimit-Reset: 1718462400
    ```

    Implement exponential backoff with jitter in your integration to handle `429` responses gracefully. If you're consistently hitting rate limits at your current plan's ceiling, consider upgrading your plan or batching signal submissions to reduce request volume. See the [FAQ — Rate Limits](/resources/faq#is-there-a-rate-limit-on-the-api) for per-plan limits.
  </Accordion>

  <Accordion title="500 Internal Server Error — Stairoids service issue">
    A `500` response indicates an unexpected error on the Stairoids side. These are rare and typically transient. Wait 30 seconds and retry the request. If the error persists for more than a few minutes, check the [Stairoids Status Page](https://status.stairoids.com) for any ongoing incidents.

    When contacting support about a `500` error, include the `request_id` from the response body — this is the fastest way for the support team to locate and investigate the failed request.
  </Accordion>
</AccordionGroup>

***

## Signal Score Not Changing

<AccordionGroup>
  <Accordion title="Scores update asynchronously — allow up to 60 seconds">
    Engagement score calculations run asynchronously after signal ingestion. When you send a signal via the API, the signal is recorded immediately (you receive a `201 Created` response), but the account or contact score is updated in a background job that typically completes within **30–60 seconds**.

    If you query an account's score immediately after ingesting a signal, you may see the old value. Wait a minute and query again. If the score still hasn't changed after 60 seconds, proceed to the next check.
  </Accordion>

  <Accordion title="Verify the signal type has a non-zero weight">
    Each signal type must have a scoring weight greater than zero to contribute to engagement scores. Navigate to **Settings → Scoring** and find the signal type you're testing. If the weight is set to `0`, the signal is ingested and stored but adds nothing to the score.

    Update the weight to a non-zero value and click **Save**. New signals of that type will contribute to scores immediately. Previously ingested signals of the same type will have their contribution recalculated on the next scoring cycle (typically within a few minutes).
  </Accordion>

  <Accordion title="Confirm the signal was attributed to the correct account">
    A signal that was attributed to the wrong account — or not attributed to any account at all — won't affect the score you're looking at. Open **Settings → Logs**, find the signal in question, and expand it to see the `account.id` and `account.domain` fields that Stairoids resolved.

    If the signal was attributed to a different account (e.g., due to domain normalization creating a different match), review your domain normalization rules under **Settings → Account Matching**.
  </Accordion>

  <Accordion title="Check whether score decay is masking new signal contributions">
    If an account has a very large historical score with strong time decay applied, new low-weight signals may not produce a visibly noticeable change in the displayed score. Navigate to the account's detail page and open the **Score History** tab to see a timeline of score changes. You can verify whether the new signal appeared as a positive delta that was offset by decay on the same cycle.

    Adjust signal weights under **Settings → Scoring** or tune the decay half-life if scores are decaying faster than your sales cycle warrants.
  </Accordion>
</AccordionGroup>

***

## Contacting Support

If you've worked through the relevant sections above and the issue persists, reach out to the Stairoids support team:

* **Email**: [support@stairoids.com](mailto:support@stairoids.com)
* **In-app chat**: Click the **?** icon in the bottom-right corner of the dashboard
* **Enterprise Slack**: Available for Enterprise plan customers via your dedicated channel

To help the team resolve your issue as quickly as possible, include the following in your message:

* **Workspace ID** — found in **Settings → General**
* **Signal ID** or **Automation ID** — visible in the Activity Log
* **`request_id`** from any relevant API response body
* The exact **error message** you're seeing
* **What you expected** to happen and **what actually happened**
* **Timestamps** of the affected events (in UTC)

<Tip>
  Every API response — including error responses — contains a `request_id` field in the JSON body. This single value allows the Stairoids support team to locate the exact request when investigating your issue. It's the most valuable piece of information you can include in a support request.
</Tip>
