# What does hubspot.deal.in_stage prove?

> Prove that the deal sits in the stage that the person authorised. Version 1.0.0, certification Provisional.

Canonical: https://provely.sh/verify/hubspot/hubspot.deal.in_stage  
Last reviewed: 2026-09-05  
Skill version: 0.1.0  
Certification: provisional  

**Prove that the deal sits in the stage that the person authorised. A created deal is not a deal in the right stage. HubSpot sets the stage from the create request, so another stage is a wrong value.**

*Contract identity.*

| Fact | Value |
| --- | --- |
| Contract id | `hubspot.deal.in_stage` |
| Version | `1.0.0` |
| Hash | `66980b7c32bb3412` |
| Completion level | `in_stage` |
| Publisher | Built and signed by Provely. |
| Certification | Provisional |
| Skill | [HubSpot CRM API 0.1.0](/verify/hubspot) |
| Valid for provider API versions | `2026-03` |

## What is the intent?

Create the deal in the pipeline stage that I name.

## What is the subject and the action?

| Member | Value |
| --- | --- |
| Subject type | `hubspot.deal` |
| Subject identity | deal_id = `$action.result.id` |
| Canonical effect | `crm.deal_create` |
| Provider operation | `POST /crm/objects/2026-03/deals` |
| Idempotency | none, retry is not safe |

## How does the evidence correlate with this operation?

| Strategy | Assurance | Keys | Required |
| --- | --- | --- | --- |
| `resource_id` | strong | deal_id from `$action.result.id` | yes |
| `fingerprint` | weak | dealname from `$input.dealname`; pipeline from `$input.pipeline` | no |

## Which evidence does the contract require?

Minimum evidence level `E2`. An independent channel is required. Minimum channels: 1.

| Channel | Level | Independence | Verifier | Description |
| --- | --- | --- | --- | --- |
| `deal_readback` | E2 | provider readback | `http` | Read the deal from the provider. A condition path is $observed.deal_readback.properties.dealstage. |
| `deal_creation_events` | E3 | provider event | `webhook` | The deal.creation notifications of this deal. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}. A condition reads $observed.deal_creation_events.count. |
| `deal_creation_events_in_account` | E3 | provider event | `webhook` | The deal.creation notifications of the account since the operation started. The webhook verifier returns {events, count, latest, earliest, types, duplicates_dropped}. A count above one shows a second deal, and HubSpot states no idempotency key to stop it. |

## Which conditions must all hold for VERIFIED?

| Condition | Meaning | Path | Operator | Expected | Evidence |
| --- | --- | --- | --- | --- | --- |
| `deal_present` | The provider holds the deal with the identifier of the answer. | `$observed.deal_readback.id` | `eq` | `$action.result.id` | `deal_readback` |
| `deal_name_matches` | The name of the deal equals the requested name. | `$observed.deal_readback.properties.dealname` | `eq` | `$input.dealname` | `deal_readback` |
| `deal_pipeline_matches` | The pipeline of the deal equals the requested pipeline. | `$observed.deal_readback.properties.pipeline` | `eq` | `$input.pipeline` | `deal_readback` |
| `deal_amount_matches` | The amount of the deal equals the requested amount. HubSpot states every property value as a string. | `$observed.deal_readback.properties.amount` | `eq` | `$input.amount` | `deal_readback` |
| `deal_created_in_window` | The provider created the deal after the operation started. | `$observed.deal_readback.createdAt` | `time_after` | `$operation.created_at` | `deal_readback` |
| `deal_creation_event` | At least one deal.creation notification names this deal. The duplicate guard reads the account channel, so an account with no event endpoint cannot verify and cannot miss a second deal either. | `$observed.deal_creation_events.count` | `gte` | `1` | `deal_creation_events` |
| `deal_in_the_authorised_stage` | The deal sits in the requested stage of the requested pipeline, and no archive removed it. | — | `all_of` | The rows below state the members. | `deal_readback` |
| `deal_stage_matches` | The stage identifier of the deal equals the requested identifier. | `$observed.deal_readback.properties.dealstage` | `eq` | `$input.dealstage` | `deal_readback` |
| `deal_stage_pipeline_matches` | The stage belongs to the requested pipeline. | `$observed.deal_readback.properties.pipeline` | `eq` | `$input.pipeline` | `deal_readback` |
| `deal_is_archived` |  | `$observed.deal_readback.archived` | `eq` | `true` | `deal_readback` |

## Which conditions give CONTRADICTED?

| Condition | Class | Reason | Path | Operator | Expected |
| --- | --- | --- | --- | --- | --- |
| `deal_in_wrong_pipeline` | wrong subject | The deal sits in a different pipeline than the intent named. | `$observed.deal_readback.properties.pipeline` | `ne` | `$input.pipeline` |
| `deal_with_another_name` | wrong subject | The deal carries a different name than the intent named. | `$observed.deal_readback.properties.dealname` | `ne` | `$input.dealname` |
| `deal_with_another_amount` | wrong amount | The deal carries a different amount than the intent stated. | `$observed.deal_readback.properties.amount` | `ne` | `$input.amount` |
| `deal_predates_operation` | pre existing state | The deal is older than the operation. It proves nothing. | `$observed.deal_readback.createdAt` | `time_before` | `$operation.created_at` |
| `duplicate_deal_present` | duplicate side effect | HubSpot created more than one deal in the account since the operation started. Do not retry. | `$observed.deal_creation_events_in_account.count` | `gt` | `1` |
| `deal_in_another_stage` | wrong subject | The deal sits in a different stage than the intent named. HubSpot sets the stage from the create request, so no wait changes it. Stop and ask a person. | `$observed.deal_readback.properties.dealstage` | `ne` | `$input.dealstage` |

## Which observed states map to a verdict before completion?

| Rule | Match | Verdict | Reason |
| --- | --- | --- | --- |
| `deal_archived` | `$observed.deal_readback.archived` eq `true` | CONTRADICTED | The deal is archived. The record left the pipeline. Ask a person. |

## How long does the runtime observe?

| Timing member | Value |
| --- | --- |
| Initial delay | 1000 ms |
| Poll interval | 5000 ms |
| Backoff | exponential factor 2, max 60000 ms |
| Maximum attempts | 40 |
| Timeout | 900000 ms |
| Stale read window | 20000 ms |
| On timeout | UNVERIFIABLE (`evidence_unavailable_before_timeout`), escalated to a person |

## Where do these rules come from?

- `hubspot.openapi#/components/schemas/Deal/properties/properties`: [hubspot.openapi](https://api.hubspot.com/public/api/spec/v1/specs), retrieved 2026-09-08
- `hubspot.docs.deals#deals/the-identifier-of-a-stage-and-of-a-pipeline`: [hubspot.docs.deals](https://developers.hubspot.com/docs/api-reference/latest/crm/objects/deals/guide), retrieved 2026-09-08
- `hubspot.docs.deals#deals/the-properties-of-a-deal`: [hubspot.docs.deals](https://developers.hubspot.com/docs/api-reference/latest/crm/objects/deals/guide), retrieved 2026-09-08
- `hubspot.docs.deals#deals/the-states-of-a-deal`: [hubspot.docs.deals](https://developers.hubspot.com/docs/api-reference/latest/crm/objects/deals/guide), retrieved 2026-09-08
- `hubspot.openapi#/components/schemas/Deal/properties/id`: [hubspot.openapi](https://api.hubspot.com/public/api/spec/v1/specs), retrieved 2026-09-08
- `hubspot.openapi#/paths/~1crm~1objects~12026-03~1deals~1{dealId}/get/responses/200`: [hubspot.openapi](https://api.hubspot.com/public/api/spec/v1/specs), retrieved 2026-09-08
- `hubspot.openapi#/components/schemas/Deal/properties/createdAt`: [hubspot.openapi](https://api.hubspot.com/public/api/spec/v1/specs), retrieved 2026-09-08
- `hubspot.events#/events/deal.creation`: [hubspot.events](https://developers.hubspot.com/docs/guides/api/app-management/webhooks), retrieved 2026-09-08
- `hubspot.docs.webhooks#webhooks/subscription-types`: [hubspot.docs.webhooks](https://developers.hubspot.com/docs/guides/api/app-management/webhooks), retrieved 2026-09-08

### Can hubspot.deal.in_stage return VERIFIED from the action response alone?

No. The minimum evidence level is E2. The action response is E1. The completion conditions read `deal_readback` and `deal_creation_events`.

### What happens after the timeout?

The verdict is UNVERIFIABLE with the reason `evidence_unavailable_before_timeout`. The operation goes to a person for review.

## Read next

- [Read the HubSpot CRM API verification page](https://provely.sh/verify/hubspot)
- [Read the hubspot.deal.created contract](https://provely.sh/verify/hubspot/hubspot.deal.created)
- [Read the hubspot.engagement.logged contract](https://provely.sh/verify/hubspot/hubspot.engagement.logged)
- [Read what a completion contract contains](https://provely.sh/contracts)
- [Read what a receipt proves](https://provely.sh/docs/receipts)
