## TL;DR
HubSpot ticket stages are identified by numeric IDs, not by the labels you see in the UI, and every stage belongs to exactly one pipeline. The API rejects a stage that doesn't exist or that lives in a different pipeline than the ticket's. Fetch the pipeline definition, read the real IDs, and send both pipeline and stage together.

## The query

```text
hubspot ticket pipeline stage id invalid
```

## Use this when

- Ticket create or update fails with an invalid stage id error
- Stage labels from the UI don't work in API calls
- Tickets appear in the wrong pipeline after creation


## Not for

- 401 unauthorized on HubSpot endpoints
- Ticket-to-contact association failures
- Contact API errors unrelated to pipelines


## Steps

### 1. Pull the pipeline definition from the API

GET the ticket pipelines endpoint and read the pipelines and their stages. The stage objects carry the numeric IDs the API actually wants. Do not guess IDs from the UI; labels and IDs are different things.

Expected output: a list of pipelines, each with stage names mapped to numeric IDs.

### 2. Send pipeline and stage together

Set both `hs_pipeline` and `hs_pipeline_stage` on the ticket. Sending a stage without its pipeline, or a stage from pipeline A with pipeline B's id, both fail. They are a pair.

Expected output: a ticket create returning 200 with the ticket in the intended stage.

### 3. Stop sending labels as IDs

The UI shows 'New' or 'Waiting on customer'; the API wants the numeric stage id. If your integration maps labels to IDs with a hardcoded table, replace it with the definition fetched in step 1, refreshed on a schedule.

Expected output: no hardcoded stage labels anywhere in the integration code.

### 4. Check custom pipelines and archived stages

If the stage ID came from an old export, the stage may have been archived or the pipeline renamed. Re-fetch and confirm the stage is active in the current pipeline definition.

Expected output: every stage ID in your config resolving to an active stage.

## Variant phrasings

### hubspot api invalid ticket stage

Steps 1 and 2 cover the fetch-the-definition, send-the-pair fix.

### hubspot ticket created in wrong pipeline

Step 2. A stage without its pipeline lets HubSpot pick the default, which is rarely what you want.

## Why it happens

HubSpot's UI speaks labels and its API speaks IDs, and the two are easy to confuse because the docs show both. Teams hardcode what they see on screen, it works until someone renames a stage or adds a second pipeline, and then every write fails. The definition endpoint is the source of truth; the UI is just a rendering.

## Edge cases

- Multiple ticket pipelines: each needs its own stage map. Don't share one map across pipelines.
- Stage IDs differ between HubSpot accounts. Never copy IDs from one portal to another.
- Deleted pipelines leave tickets in limbo. HubSpot migrates them, but your cached IDs go stale.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_83g4NOVT1_s7540zjN4g_g
