---
title: "Business State"
method: POST
path: "/margot/actions/business_state"
tags: ["margot"]
---

# Business State

`POST /margot/actions/business_state`

## Request

- Base URL: `https://api.nanocorp.so` (the document declares no server; this is the origin it was published from)
- URL: `https://api.nanocorp.so/margot/actions/business_state`
- Auth: HTTP bearer

Why one of the caller's businesses runs, sells and chats the way it does now (ungated read).

The turn gates and the checkout links' state, from the code that enforces them
(:mod:`use_cases.support.business_state`).

## Request body

- MargotActionRequest: Common request body for every Margot action. Identity comes from the request: on a customer ticket Parahelp's tool fills it from the ticket's requester (never from the message text), on a team call the teammate names the founder. The backend resolves `external_id` (our `user.id`) or a unique `email` to the account server-side; it never trusts a company/conglomerate id from the body.
  - `external_id` string, nullable: The founder's NanoCorp user id (external_id on the helpdesk contact).
  - `email` string, nullable: The founder's email. Used as a fallback identity and a cross-check.
  - `company` string, nullable: Optional company name/handle hint, resolved against the caller's own companies.
  - `limit` integer, nullable: Optional row limit for list actions.

## Response `200`

Successful Response

- BusinessStateResponse: Why one of the founder's businesses runs, sells and talks the way it does right now. Facts and the app's own gate messages only: no ids, no internal flags beyond the owner's own switches.
  - `found` boolean
  - `company` CompanySummary: Customer-safe view of one of the caller's companies.
    - `name` string, required
    - `handle` string, required
    - `status` string, required
    - `custom_domain` string, nullable
    - `custom_domain_verified` boolean
  - `harness` string, nullable: 'v3' or 'classic' (the older dashboard and controls).
  - `scheduled_runs` string, nullable: 'on' or 'off': the Scheduled runs switch in Ops. 'off' is what the app calls 'paused'; chat still works. Null for a business that is not founded yet or is archived.
  - `chat` SessionGateState: Whether one kind of agent turn may start now, in the app's own words.
    - `allowed` boolean, required
    - `reason` string, nullable: Why it may not start: draft (the business is not founded yet), archived, scheduled_runs_off (Scheduled runs is off in Ops; chat still works), light_plan (the Light plan keeps one business active and parked this one: upgrading to Founder lets it sell again, then the owner turns Scheduled runs and Website back on), out_of_credits, plan (the plan does not allow agent turns) or classic_harness (the business must be switched to v3 from its page before its agent works again). Null when allowed.
    - `message` string, nullable: The message the app shows the owner. Null when allowed.
  - `scheduled` SessionGateState: Whether one kind of agent turn may start now, in the app's own words.
    - `allowed` boolean, required
    - `reason` string, nullable: Why it may not start: draft (the business is not founded yet), archived, scheduled_runs_off (Scheduled runs is off in Ops; chat still works), light_plan (the Light plan keeps one business active and parked this one: upgrading to Founder lets it sell again, then the owner turns Scheduled runs and Website back on), out_of_credits, plan (the plan does not allow agent turns) or classic_harness (the business must be switched to v3 from its page before its agent works again). Null when allowed.
    - `message` string, nullable: The message the app shows the owner. Null when allowed.
  - `site_paused` boolean: The owner turned the Website switch off.
  - `selling_paused` boolean: Checkout is off: by the owner, by the plan ending, or by the Light plan parking it.
  - `selling_paused_by_plan_expiry` boolean: Checkout was turned off because the plan ended, not by the owner.
  - `parked_by_light_plan` boolean: The Light plan keeps one business active and parked this one (site, checkout and scheduled runs off). Upgrading to Founder restores its checkout only; the owner then turns Scheduled runs and the Website switch back on.
  - `outbound_email_paused` boolean: The owner turned Outbound email off.
  - `prospecting_paused` boolean: The owner turned Prospecting off.
  - `ads_enabled` boolean: Ads are turned on for this business.
  - `checkout` CheckoutLinkState: Whether one of the business's two general checkout links takes payments right now.
    - `taking_payments` boolean, required
    - `reason` string, nullable: Why it does not: no_link (no product was ever sold, so the link does not exist yet), link_off, archived, selling_paused (the owner turned Checkout off in Ops), light_plan (the Light plan parked this business), link_paused, plan_expired, free_plan (the free plan sells nothing: the checkout opens with the Founder plan), mixed_currencies (products priced in two currencies cannot share one checkout), plans_only (the business sells only monthly plans: the general link sells one-time products only, so it shows 'isn't taking payments'; each plan is sold from the site and tested with its own TEST LINK, which appears when hovering the plan row in Products) or no_products. Null when it takes payments.
    - `one_time_products` integer: One-time products this link sells.
  - `test_checkout` CheckoutLinkState: Whether one of the business's two general checkout links takes payments right now.
    - `taking_payments` boolean, required
    - `reason` string, nullable: Why it does not: no_link (no product was ever sold, so the link does not exist yet), link_off, archived, selling_paused (the owner turned Checkout off in Ops), light_plan (the Light plan parked this business), link_paused, plan_expired, free_plan (the free plan sells nothing: the checkout opens with the Founder plan), mixed_currencies (products priced in two currencies cannot share one checkout), plans_only (the business sells only monthly plans: the general link sells one-time products only, so it shows 'isn't taking payments'; each plan is sold from the site and tested with its own TEST LINK, which appears when hovering the plan row in Products) or no_products. Null when it takes payments.
    - `one_time_products` integer: One-time products this link sells.
  - `plans` integer: Active monthly plans. A plan is never on the general links: the site sells it, and its TEST LINK in Products tests it.
  - `plan_tier` string, nullable
  - `plan_expired` boolean
  - `free_plan` boolean: The account is on the free plan: chat and edits run on its free credits, while checkout, outbound email, a second business and the agent's daily work after the first days take the Founder plan.
  - `credit_balance` number, nullable
  - `credit_floor` number, nullable: Below this balance no agent turn starts.

## Other responses

- `422`: Validation Error

## Changes

- **2026-10-23** `291bb76b720b`: 1 info
  - added the optional property `free_plan` to the response with the `200` status
- **2026-10-06** `05989a402d6e`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/nanocorp/apis/nanocorp-api/changes/margot/actions/business_state/post.md)

---

[API](https://skmtc.dev/nanocorp/apis/nanocorp-api.md) - [All operations](https://skmtc.dev/nanocorp/apis/nanocorp-api/llms.txt) - [OpenAPI document](https://skmtc.dev/nanocorp/apis/nanocorp-api/revisions/291bb76b720b?raw)
