Public HTTPS · No private SDK
Formation HTTP quickstart for outside agents
Discover the live catalog and formation OpenAPI, POST one qualification from operator-supplied conditions, stop on terminal outcomes, optionally prepare a provisional case, then hand the claim/review link to a human. Agents never claim, pay, or invent credentials.
Demonstrated case-qualified route: $399 plus state filing fees. EIN support can take 2–3 business days for qualifying cases; timing depends on the case and is not a universal guarantee. Not every business needs a US entity or EIN. Direct IRS EIN resources remain available.
Human surfaces (not SDKs): formation assessment · partner decision. This page invents no private package or unpublished npm client.
01 · Discover
Public catalog and formation OpenAPI
-
Service catalog (read-only GET):
https://ein.llc/api/v1/service-catalog -
Formation HTTP OpenAPI (assess, prepare, claim, review, grants, status):
https://ein.llc/api/agent/v1/openapi.json -
Catalog-only OpenAPI (does not describe formation mutations):
https://ein.llc/openapi.json
ORIGIN=https://ein.llc
curl --fail-with-body -sS --max-time 15 "$ORIGIN/api/v1/service-catalog"
curl --fail-with-body -sS --max-time 15 "$ORIGIN/api/agent/v1/openapi.json" const ORIGIN = process.env.ORIGIN || "https://ein.llc";
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), 15_000);
const openapi = await fetch(`${ORIGIN}/api/agent/v1/openapi.json`, {
signal: ctrl.signal,
});
clearTimeout(t);
if (!openapi.ok) throw new Error(`OpenAPI request failed: ${openapi.status}`);
console.log(openapi.status, await openapi.json()); 02 · Qualify once
POST assessment from operator-supplied conditions
Anonymous POST /api/agent/v1/assessments accepts
AssessmentInput fields only (non-sensitive): goal,
hasUsEntity, hasEin,
jurisdictionKnown,
selectedState,
providerRequiresUsEntity,
providerRequiresEin,
foreignOwnedCaution. Tri-state fields use
yes / no /
unknown. Never creates checkout.
Positive path (required_for_selected_path · offer llc-ein-399):
ORIGIN=https://ein.llc
curl --fail-with-body -sS --max-time 15 -X POST "$ORIGIN/api/agent/v1/assessments" \
-H "content-type: application/json" \
-d '{
"goal": "Accept Stripe for a SaaS product",
"hasUsEntity": "no",
"hasEin": "no",
"providerRequiresUsEntity": "yes",
"providerRequiresEin": "yes",
"selectedState": "Wyoming",
"foreignOwnedCaution": false
}' const ORIGIN = process.env.ORIGIN || "https://ein.llc";
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), 15_000);
const res = await fetch(`${ORIGIN}/api/agent/v1/assessments`, {
method: "POST",
headers: { "content-type": "application/json" },
signal: ctrl.signal,
body: JSON.stringify({
goal: "Accept Stripe for a SaaS product",
hasUsEntity: "no",
hasEin: "no",
providerRequiresUsEntity: "yes",
providerRequiresEin: "yes",
selectedState: "Wyoming",
foreignOwnedCaution: false,
}),
});
clearTimeout(t);
if (!res.ok) throw new Error(`Assessment request failed: ${res.status}`);
const body = await res.json();
console.log(res.status, body.assessment?.outcome, body.assessment?.offer?.serviceId); Already satisfied (terminal — do not prepare):
ORIGIN=https://ein.llc
curl --fail-with-body -sS --max-time 15 -X POST "$ORIGIN/api/agent/v1/assessments" \
-H "content-type: application/json" \
-d '{
"goal": "Continue an existing US business",
"hasUsEntity": "yes",
"hasEin": "yes"
}' const ORIGIN = process.env.ORIGIN || "https://ein.llc";
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), 15_000);
const res = await fetch(`${ORIGIN}/api/agent/v1/assessments`, {
method: "POST",
headers: { "content-type": "application/json" },
signal: ctrl.signal,
body: JSON.stringify({
goal: "Continue an existing US business",
hasUsEntity: "yes",
hasEin: "yes",
}),
});
clearTimeout(t);
if (!res.ok) throw new Error(`Assessment request failed: ${res.status}`);
const body = await res.json();
console.log(res.status, body.assessment?.outcome, body.assessment?.offer); 03 · Stop outcomes
Terminal results — do not prepare
already_satisfied— entity and EIN already reported.not_needed_now— existing capability covers the path.-
insufficient_information— gather non-sensitive facts; uncertain stays uncertain.
The API refuses prepare for already_satisfied and
not_needed_now. Treat all three as stops for agent
automation.
04 · Optional provisional preparation
POST applications only when qualification continues
POST /api/agent/v1/applications creates a non-sensitive
provisional case. No idempotency key — each call creates a new case.
Supply intendedEmail for a claimable handoff. Missing or
invalid email returns complete: false without a claim
token. Preparation never approves or pays.
# WARNING: each successful call creates a NEW application. Prefer disposable ORIGIN.
ORIGIN=https://ein.llc
curl --fail-with-body -sS --max-time 15 -X POST "$ORIGIN/api/agent/v1/applications" \
-H "content-type: application/json" \
-d '{
"intendedEmail": "owner@example.com",
"preparation": {
"goal": "Accept Stripe for a SaaS product",
"jurisdiction": "Wyoming",
"existingEntityStatus": "none",
"assessmentOutcome": "required_for_selected_path",
"providerPath": "stripe"
}
}' 05 · Human claim and review
Exact link shapes — humans claim; agents do not
-
reviewUrl:https://ein.llc/review/{applicationId}(path shape/review/{applicationId}) -
claimUrl:https://ein.llc/review/{applicationId}?claim={claimToken} - Partner decision (human confirm scope): https://ein.llc/agents/partner-decision
The intended human signs in with a verified Firebase email matching
intendedEmail, claims if needed, completes confidential
intake, and pays only through existing merchant checkout after review. Agents do not
claim.
06 · Scoped status after a human grant
GET status only with Bearer AgentGrant
After the human issues a revocable status grant
(POST .../grants with Firebase auth), the agent may call
GET /api/agent/v1/applications/{applicationId}/status
with Authorization: Bearer <AgentGrant>. Status is
redacted: no passport, SSN, EIN digits, or document URLs. Payment is not EIN issued.
ORIGIN=https://ein.llc
APPLICATION_ID=app_example
AGENT_GRANT=replace-with-human-issued-grant
curl --fail-with-body -sS --max-time 15 \
-H "Authorization: Bearer $AGENT_GRANT" \
"$ORIGIN/api/agent/v1/applications/$APPLICATION_ID/status" Boundaries
- No private repo paths, no private activation-client packages, and no unpublished npm client.
- No new auth mechanism on this page — use the published OpenAPI security schemes.
- Do not create production prepare/claim/pay traffic as QA; use a disposable local origin for mutate examples.
- Offer id when present:
llc-ein-399· $399 + state filing fees · 2–3-business-day EIN route for qualifying cases.