All twins

Service twin · API only

Salesforce

Test revenue agents that manage leads, opportunities, accounts, and customer follow-up.

API onlydomain twinREST · MCP · CLI
Terminal
$ uv tool install blobfish-cli
$ blobfish twin login
$ blobfish twin-runs create --twins salesforce --ttl 60 --wait

What’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.

Operations52
Reads20
Writes32
Entities9
Lifecycles6

Seeded entities

EntityTableFieldsAbout
userusers7Salesforce user — the record owner referenced by owner_id across the CRM.
accountaccounts16Account sobject — company record with billing address, firmographics, and a governed engagement lifecycle.
contactcontacts13Contact sobject — person on an account with a consent-aware lifecycle.
leadleads16Lead sobject — unqualified prospect with the Salesforce default status picklist and conversion lifecycle.
opportunityopportunities15Opportunity sobject — revenue deal carrying the full Salesforce default stage lifecycle from prospecting to closed_won/closed_lost.
opportunity_line_itemopportunity_line_items8OpportunityLineItem sobject — product line on an opportunity.
tasktasks11Task sobject — follow-up activity with the Salesforce default status picklist (not_started → completed).
eventevents11Event sobject — calendar activity (calls, meetings, demos) logged against accounts and people.
casecases11Case sobject — service request tied to the responsible account and contact (modeled on the Salesforce REST API; outside the Composio toolkit's surface).

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.

account.status

prospect → active → at_risk → inactive
  • approve: prospect active

contact.status

new → qualified → active → opted_out
  • verify: new qualified

lead.status

open_not_contacted → working_contacted → closed_converted → closed_not_converted
  • convert: open_not_contacted|working_contacted closed_converted

opportunity.stage

prospecting → qualification → needs_analysis → value_proposition → id_decision_makers → perception_analysis → proposal_price_quote → negotiation_review → closed_won → closed_lost
  • close_won: proposal_price_quote|negotiation_review closed_won
  • close_lost: prospecting|qualification|needs_analysis|value_proposition|id_decision_makers|perception_analysis|proposal_price_quote|negotiation_review closed_lost

task.status

not_started → in_progress → waiting → completed → deferred
  • complete: not_started|in_progress|waiting|deferred completed

case.status

new → working → waiting_customer → escalated → closed
  • escalate: working|waiting_customer escalated
  • close: new|working|waiting_customer|escalated closed

Three surfaces, one state

Mount Salesforce 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:

API
$ 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":["salesforce"],"ttl_minutes":60}'

Known limitations