← Deal Launch / API
Get a token

Driving Deal Launch from your own code

Deal Launch is a SkillSafe app. Everything the page does — estimating a lane, running it, streaming the reply — is an HTTP call you can make yourself. The base URL is https://api.skillsafe.ai/v1/app-api and the app slug is deal-launch.

The free part stays in your browser.

The fact-set reader — the financial table parser, the growth and margin arithmetic, the identifier index and the flags — runs entirely client-side in dealscan.js and has no endpoint. If you are driving the API you compute or supply prescan_facts yourself; the model is instructed not to contradict it.

The envelope

Every response is {"data": ...} on success or {"error": {"code", "message", "details"}} on failure, with the HTTP status matching the code.

Error codes

codestatuswhat it means
UNAUTHORIZED401No token, or a token that has expired. Mint a guest token or sign in again.
FORBIDDEN403The token belongs to another app. Tokens are scoped per app slug.
NOT_FOUND404Wrong path. Every path on this page begins /v1/app-api.
VALIDATION_ERROR400The input failed validation — usually a missing task or a non-object body.
INSUFFICIENT_CREDITS402The balance is below min_credits. Call /estimate first.
RATE_LIMITED429Too many requests. Back off; do not retry in a tight loop.
JOB_FAILED500The model run failed after it started. The error SSE event carries the job id.

The task field comes first

Deal Launch is one app with one system prompt and five lanes. Every run input must carry a task field naming the lane; the prompt routes on it. Send an unknown value and the model picks the closest lane and says which one it chose, which is almost never what you wanted.

tasklanesource skillwhat the reply carries
teaserAnonymous teaser@anthropics/teaserFive named sections and an empty rows array. The reply is re-checked in the browser against the identifier index; a teaser that names the company is flagged to the user.
buyersBuyer universe@anthropics/buyer-listRows carry buyer, type, tier, rationale, fit, concerns, priority.
processProcess letter@anthropics/process-letterBoth a letter body and a timetable. Every date is parsed and turned into an iCalendar file, so only real calendar dates are accepted.
cimCIM outline@anthropics/cim-builderRows carry section, subsection, evidence, owner (company/adviser/both) and status (have/partial/missing).
diligenceDiligence request list@anthropics/dd-checklistRows carry ref, workstream, request, priority, format and why.

Input fields

fieldtypenotes
taskstringRequired. One of the five lane ids above.
factsstringRequired. The company fact set. The app clips at 24,000 characters by removing the middle on line boundaries and marking the cut in-band.
deal_typestringmajority-sale, minority-growth, carve-out or full-exit.
audiencestringboth, strategic, sponsor or management.
stagestringpre-launch, phase-one or phase-two.
identifiers_maskedbooleanWhether facts has already had its identifying details replaced.
contextstringOptional constraints. Treated as binding by the prompt.
prescan_factsobjectThe client-side read: parsed figures, computed growth and margins, the identifier list and the flags. The prompt requires one coverage_check entry per applicable flag id. Each entry of prescan_facts.identifiers carries id, kind and replacement; when identifiers_masked is false it also carries literal, the exact string in facts that the replacement stands for — without it the model cannot tell which words to replace. When masking is on, literal is deliberately withheld so the prescan block does not undo the masking.
upstreamobjectOptional. A digest of an earlier lane's output when you are chaining lanes.

The output envelope — identical for every lane

The model returns one JSON object. The app takes the text from the first { to the last } and parses it; only the inner body differs per lane.

{
  "lane": "teaser",
  "title": "…",
  "headline": "…",
  "verdict": "ready-to-send | needs-work | blocked",
  "readiness": 0,
  "summary": "…",
  "sections": [
    {
      "id": "overview",
      "heading": "…",
      "body": "…",
      "bullets": [
        "…"
      ]
    }
  ],
  "rows": [],
  "gaps": [
    {
      "id": "G1",
      "need": "…",
      "why": "…",
      "severity": "high"
    }
  ],
  "coverage_check": [
    {
      "flag_id": "DL-040",
      "status": "addressed",
      "note": "…"
    }
  ],
  "anonymity": {
    "claimed_anonymous": true,
    "notes": "…"
  },
  "artifact": {
    "kind": "markdown",
    "filename": "teaser.md",
    "content": "# …"
  }
}

One worked example per lane

Each block is the exact body to POST to /estimate, /run or /run-stream for that lane, trimmed for length.

Anonymous teaser — task: "teaser"

{
  "task": "teaser",
  "facts": "Company: Northwind Compliance Systems Ltd\\nSector: regulatory compliance software\\n| Year | Revenue | EBITDA |\\n| 2024 | 24.9 | 5.4 |\\n| 2025 | 31.2 | 7.8 |",
  "deal_type": "majority-sale",
  "audience": "both",
  "stage": "pre-launch",
  "identifiers_masked": true,
  "context": "Bids wanted before the end of the financial year.",
  "prescan_facts": {
    "readiness": 88,
    "readiness_tier": "launch-ready",
    "currency": "GBP",
    "years": [
      2024,
      2025
    ],
    "revenue_cagr_pct": 25.3,
    "latest_growth_pct": 25.3,
    "ebitda_margins_pct": [
      {
        "year": 2024,
        "pct": 21.7
      },
      {
        "year": 2025,
        "pct": 25.0
      }
    ],
    "largest_customer_pct": 14,
    "size_band": "10m to 50m",
    "identifiers": [
      {
        "id": "ID-1",
        "kind": "company",
        "replacement": "[the Company]"
      }
    ],
    "flags": [
      {
        "id": "DL-040",
        "severity": "high",
        "title": "13 identifying details are in this paste",
        "lanes": [
          "teaser"
        ]
      }
    ]
  }
}

Buyer universe — task: "buyers"

{
  "task": "buyers",
  "facts": "Company: Northwind Compliance Systems Ltd\\nSector: regulatory compliance software\\n| Year | Revenue | EBITDA |\\n| 2024 | 24.9 | 5.4 |\\n| 2025 | 31.2 | 7.8 |",
  "deal_type": "majority-sale",
  "audience": "both",
  "stage": "pre-launch",
  "identifiers_masked": true,
  "context": "Bids wanted before the end of the financial year.",
  "prescan_facts": {
    "readiness": 88,
    "readiness_tier": "launch-ready",
    "currency": "GBP",
    "years": [
      2024,
      2025
    ],
    "revenue_cagr_pct": 25.3,
    "latest_growth_pct": 25.3,
    "ebitda_margins_pct": [
      {
        "year": 2024,
        "pct": 21.7
      },
      {
        "year": 2025,
        "pct": 25.0
      }
    ],
    "largest_customer_pct": 14,
    "size_band": "10m to 50m",
    "identifiers": [
      {
        "id": "ID-1",
        "kind": "company",
        "replacement": "[the Company]"
      }
    ],
    "flags": [
      {
        "id": "DL-040",
        "severity": "high",
        "title": "13 identifying details are in this paste",
        "lanes": [
          "teaser"
        ]
      }
    ]
  }
}

Process letter — task: "process"

{
  "task": "process",
  "facts": "Company: Northwind Compliance Systems Ltd\\nSector: regulatory compliance software\\n| Year | Revenue | EBITDA |\\n| 2024 | 24.9 | 5.4 |\\n| 2025 | 31.2 | 7.8 |",
  "deal_type": "majority-sale",
  "audience": "both",
  "stage": "pre-launch",
  "identifiers_masked": true,
  "context": "Bids wanted before the end of the financial year.",
  "prescan_facts": {
    "readiness": 88,
    "readiness_tier": "launch-ready",
    "currency": "GBP",
    "years": [
      2024,
      2025
    ],
    "revenue_cagr_pct": 25.3,
    "latest_growth_pct": 25.3,
    "ebitda_margins_pct": [
      {
        "year": 2024,
        "pct": 21.7
      },
      {
        "year": 2025,
        "pct": 25.0
      }
    ],
    "largest_customer_pct": 14,
    "size_band": "10m to 50m",
    "identifiers": [
      {
        "id": "ID-1",
        "kind": "company",
        "replacement": "[the Company]"
      }
    ],
    "flags": [
      {
        "id": "DL-040",
        "severity": "high",
        "title": "13 identifying details are in this paste",
        "lanes": [
          "teaser"
        ]
      }
    ]
  }
}

CIM outline — task: "cim"

{
  "task": "cim",
  "facts": "Company: Northwind Compliance Systems Ltd\\nSector: regulatory compliance software\\n| Year | Revenue | EBITDA |\\n| 2024 | 24.9 | 5.4 |\\n| 2025 | 31.2 | 7.8 |",
  "deal_type": "majority-sale",
  "audience": "both",
  "stage": "pre-launch",
  "identifiers_masked": true,
  "context": "Bids wanted before the end of the financial year.",
  "prescan_facts": {
    "readiness": 88,
    "readiness_tier": "launch-ready",
    "currency": "GBP",
    "years": [
      2024,
      2025
    ],
    "revenue_cagr_pct": 25.3,
    "latest_growth_pct": 25.3,
    "ebitda_margins_pct": [
      {
        "year": 2024,
        "pct": 21.7
      },
      {
        "year": 2025,
        "pct": 25.0
      }
    ],
    "largest_customer_pct": 14,
    "size_band": "10m to 50m",
    "identifiers": [
      {
        "id": "ID-1",
        "kind": "company",
        "replacement": "[the Company]"
      }
    ],
    "flags": [
      {
        "id": "DL-040",
        "severity": "high",
        "title": "13 identifying details are in this paste",
        "lanes": [
          "teaser"
        ]
      }
    ]
  }
}

Diligence request list — task: "diligence"

{
  "task": "diligence",
  "facts": "Company: Northwind Compliance Systems Ltd\\nSector: regulatory compliance software\\n| Year | Revenue | EBITDA |\\n| 2024 | 24.9 | 5.4 |\\n| 2025 | 31.2 | 7.8 |",
  "deal_type": "majority-sale",
  "audience": "both",
  "stage": "pre-launch",
  "identifiers_masked": true,
  "context": "Bids wanted before the end of the financial year.",
  "prescan_facts": {
    "readiness": 88,
    "readiness_tier": "launch-ready",
    "currency": "GBP",
    "years": [
      2024,
      2025
    ],
    "revenue_cagr_pct": 25.3,
    "latest_growth_pct": 25.3,
    "ebitda_margins_pct": [
      {
        "year": 2024,
        "pct": 21.7
      },
      {
        "year": 2025,
        "pct": 25.0
      }
    ],
    "largest_customer_pct": 14,
    "size_band": "10m to 50m",
    "identifiers": [
      {
        "id": "ID-1",
        "kind": "company",
        "replacement": "[the Company]"
      }
    ],
    "flags": [
      {
        "id": "DL-040",
        "severity": "high",
        "title": "13 identifying details are in this paste",
        "lanes": [
          "teaser"
        ]
      }
    ]
  }
}

Step 1 — a token

Every call needs Authorization: Bearer <token>. A guest token is minted in one call and is enough for /me and /estimate; running a lane is metered and needs a personal token from signing in. The easiest way to get a personal token is the token page, which reads the one this browser already holds. Put it in an environment variable your shell already has — never paste it into a file you commit.

curl -s -X POST "https://api.skillsafe.ai/v1/app-api/guest" \
  -H "Authorization: Bearer $DEAL_LAUNCH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "slug": "deal-launch"
}'

Step 2 — who am I, and what is the balance

GET /me returns subject_type (user or guest), subject_id and credits. Compare the balance against the estimate below before running; a 402 after submit is avoidable.

curl -s "https://api.skillsafe.ai/v1/app-api/me" \
  -H "Authorization: Bearer $DEAL_LAUNCH_TOKEN"

Step 3 — estimate the lane (free, no job)

POST /estimate returns model, model_alias, markup_bps, hold_credits, min_credits and sponsor_enabled. It costs nothing and creates no job. Estimate the lane you are about to run — the hold differs per lane because the prompts and output caps differ. hold_credits is what is reserved, not what you pay; settlement is usually far lower.

curl -s -X POST "https://api.skillsafe.ai/v1/app-api/estimate" \
  -H "Authorization: Bearer $DEAL_LAUNCH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "task": "teaser",
  "facts": "Company: Northwind Compliance Systems Ltd\\nSector: regulatory compliance software\\n| Year | Revenue | EBITDA |\\n| 2024 | 24.9 | 5.4 |\\n| 2025 | 31.2 | 7.8 |",
  "deal_type": "majority-sale",
  "audience": "both",
  "stage": "pre-launch",
  "identifiers_masked": true,
  "context": "Bids wanted before the end of the financial year.",
  "prescan_facts": {
    "readiness": 88,
    "readiness_tier": "launch-ready",
    "currency": "GBP",
    "years": [
      2024,
      2025
    ],
    "revenue_cagr_pct": 25.3,
    "latest_growth_pct": 25.3,
    "ebitda_margins_pct": [
      {
        "year": 2024,
        "pct": 21.7
      },
      {
        "year": 2025,
        "pct": 25.0
      }
    ],
    "largest_customer_pct": 14,
    "size_band": "10m to 50m",
    "identifiers": [
      {
        "id": "ID-1",
        "kind": "company",
        "replacement": "[the Company]"
      }
    ],
    "flags": [
      {
        "id": "DL-040",
        "severity": "high",
        "title": "13 identifying details are in this paste",
        "lanes": [
          "teaser"
        ]
      }
    ]
  }
}'

Step 4 — run it, and poll

POST /run returns {"job_id": "…"}. Always send an Idempotency-Key header. The app uses deal-launch:<lane>:<hash of the input>:a<attempt>, so a network blip cannot bill twice and two lanes over the same fact set never collide on one key.

curl -s -X POST "https://api.skillsafe.ai/v1/app-api/run" \
  -H "Authorization: Bearer $DEAL_LAUNCH_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "task": "buyers",
  "facts": "Company: Northwind Compliance Systems Ltd\\nSector: regulatory compliance software\\n| Year | Revenue | EBITDA |\\n| 2024 | 24.9 | 5.4 |\\n| 2025 | 31.2 | 7.8 |",
  "deal_type": "majority-sale",
  "audience": "both",
  "stage": "pre-launch",
  "identifiers_masked": true,
  "context": "Bids wanted before the end of the financial year.",
  "prescan_facts": {
    "readiness": 88,
    "readiness_tier": "launch-ready",
    "currency": "GBP",
    "years": [
      2024,
      2025
    ],
    "revenue_cagr_pct": 25.3,
    "latest_growth_pct": 25.3,
    "ebitda_margins_pct": [
      {
        "year": 2024,
        "pct": 21.7
      },
      {
        "year": 2025,
        "pct": 25.0
      }
    ],
    "largest_customer_pct": 14,
    "size_band": "10m to 50m",
    "identifiers": [
      {
        "id": "ID-1",
        "kind": "company",
        "replacement": "[the Company]"
      }
    ],
    "flags": [
      {
        "id": "DL-040",
        "severity": "high",
        "title": "13 identifying details are in this paste",
        "lanes": [
          "teaser"
        ]
      }
    ]
  }
}'

Then poll GET /jobs/{job_id} until status is terminal. The reply text is in output.output.

curl -s "https://api.skillsafe.ai/v1/app-api/jobs/job_123" \
  -H "Authorization: Bearer $DEAL_LAUNCH_TOKEN"

Step 5 — stream it instead

POST /run-stream returns text/event-stream with four event names: job (the job id, as soon as it exists), delta ({"text": "…"} chunks), done ({job_id, status, charged_credits, output, truncated}) and error. The app uses this lane and advances its progress card on the envelope keys as they arrive.

curl -N -X POST "https://api.skillsafe.ai/v1/app-api/run-stream" \
  -H "Authorization: Bearer $DEAL_LAUNCH_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: deal-launch:cim:9f2a1c04:a1" \
  -d '{
  "task": "cim",
  "facts": "Company: Northwind Compliance Systems Ltd\\nSector: regulatory compliance software\\n| Year | Revenue | EBITDA |\\n| 2024 | 24.9 | 5.4 |\\n| 2025 | 31.2 | 7.8 |",
  "deal_type": "majority-sale",
  "audience": "both",
  "stage": "pre-launch",
  "identifiers_masked": true,
  "context": "Bids wanted before the end of the financial year.",
  "prescan_facts": {
    "readiness": 88,
    "readiness_tier": "launch-ready",
    "currency": "GBP",
    "years": [
      2024,
      2025
    ],
    "revenue_cagr_pct": 25.3,
    "latest_growth_pct": 25.3,
    "ebitda_margins_pct": [
      {
        "year": 2024,
        "pct": 21.7
      },
      {
        "year": 2025,
        "pct": 25.0
      }
    ],
    "largest_customer_pct": 14,
    "size_band": "10m to 50m",
    "identifiers": [
      {
        "id": "ID-1",
        "kind": "company",
        "replacement": "[the Company]"
      }
    ],
    "flags": [
      {
        "id": "DL-040",
        "severity": "high",
        "title": "13 identifying details are in this paste",
        "lanes": [
          "teaser"
        ]
      }
    ]
  }
}'

Step 6 — what to do with the reply

Rate limits and cost