Service twin · API only
HubSpot
Test sales and support agents that update CRM records, move deals, and manage customer workflows.
$ uv tool install blobfish-cli
$ blobfish twin login
$ blobfish twin-runs create --twins hubspot --ttl 60 --waitWhat’s inside
A deterministic, seeded, resettable replica: every operation below executes real state transitions against the twin’s own SQLite state — reads are hash-invariant, writes produce inspectable diffs, and reset restores the seed baseline.
Seeded entities
| Entity | Table | Fields | About |
|---|---|---|---|
| owner | owners | 6 | CRM owner (rep) that records are assigned to. |
| company | companies | 10 | Company record moving through the marketing-to-customer lifecycle. |
| contact | contacts | 9 | Person at a company with a consent-aware qualification lifecycle. |
| pipeline | pipelines | 5 | Ordered pipeline a CRM object type moves through. |
| pipeline_stage | pipeline_stages | 6 | One stage of a pipeline with its win probability. |
| deal | deals | 13 | Revenue deal tied to a company, pipeline stage, and owner. |
| engagement | engagements | 9 | Logged activity (call, email, meeting, note, task) against a contact or deal. |
Guarded lifecycles
These state machines are enforced, not decorative: an action whose fromstate doesn’t match is rejected the way the production service rejects it.
company.lifecycle_stage
contact.lifecycle_stage
qualify: lead|marketing_qualified → sales_qualified
deal.status
win: open → wonlose: open → lost
Three surfaces, one state
Mount HubSpot in a twin environment and the same seeded state serves vendor-shaped REST operations, an MCP endpoint for tool calling, and a generated bf-twin CLI — with copy-on-write sessions per rollout and a one-call reset to the seed baseline. Prefer raw HTTP? The same create works with curl:
$ curl -sS -X POST https://blobfish.ai/api/v1/twin/environments \
-H "X-API-Key: $BLOBFISH_API_KEY" -H "Content-Type: application/json" \
-d '{"services":["hubspot"],"ttl_minutes":60}'Known limitations
Spec-grounded surface with synthetic seeded values; operations outside the spec are not mounted.