← Wire Ready
API
Tokens

Run Wire Ready from your own code

All three metered lanes are available over HTTP and each returns one JSON object. The division of labour: the page checks the brief against the skill's ten required questions, lists the release type's mandatory elements, writes the designation (for immediate release, or the embargo with its time zone), formats the dateline for the target market, names the market's style guide and send window, and - for a pasted release - runs every mechanical quality check (lead length, total length, banned phrases, "said", third person, boilerplate, contact, end mark) with its evidence - all free, in presskit.js. The run finds the angle, drafts the release or settles the review; the page then holds the reply to its own facts (pressreply.js). The run never invents a fact, a number, a person or a quote the input does not hold.

Base URL and the response shape

Every endpoint lives under https://api.skillsafe.ai/v1/app-api, and every response has one shape:

{ "ok": true,  "data":  { ... } }
{ "ok": false, "error": { "code": "...", "message": "..." } }

The token is minted for this app (the guest call takes {"slug":"wire-ready"}), so no slug header is needed afterwards. Send it as Authorization: Bearer YOUR_TOKEN. The run body is the input object, sent bare.

StatusCodeMeaning
400validation_errorThe body is not a JSON object, or one of its keys (task, brief, headline, draft, facts) is missing. Send all five; headline and draft may be empty strings.
401unauthorizedNo token, or a stale one. Mint a guest token or sign in again.
402insufficient_creditsThe balance is under min_credits. Price with /estimate first.
403forbiddenA guest token tried to run: all three lanes are metered and need a personal sign-in.
404not_foundUnknown job id.
429rate_limitedBack off and retry.
5xxserver_errorTransient. Retry with the same Idempotency-Key so a retry never double-bills.

The task field comes first

Three lanes, chosen by task, in the order the skill works:

A missing or unknown task is answered as angle. Every lane sends the same five fields: headline is filled only for a draft and draft only for a review; both are empty strings otherwise. The facts are the page's worked-out lines - different per lane - and a line starting "must:" is a rule the reply has to hold.

The input

FieldRequiredWhat
taskyesangle, draft or review. If it is missing or none of these, do angle and set "task": "angle".
briefyesthe announcement as the organizer entered it, one labelled line per item; "not given" means not given.
headlineyes (empty unless task is draft)draft task only: the headline the organizer chose, or empty.
draftyes (empty unless task is review)review task only: the press release to review, as pasted.
factsyesthe page's worked-out lines for this task: for angle, how many required questions the brief answers, the release type and its mandatory elements, the market's style rules and the numbers in the brief; for draft, also the designation, the dateline, the chosen headline, the speakers, the boilerplate, the contact and the send window; for review, every quality check as n. id | status | evidence, the page's verdict and the expected designation and dateline. A line starting "must:" applies to your reply.
retry_notenooptional; if present, your previous reply was unusable - follow it.

The rules the model applies

From the source skill, @samber/press-release-writer - the only standard the run applies:

House rules

The replies

angle

Find the news angle and propose headlines, before anything is drafted.

  1. summary - one sentence, at most 40 words: the angle's strength and the next step.
  2. angle - the news angle, one sentence.
  3. strength - exactly strong, workable or weak. weak when no news value holds or nothing has actually changed.
  4. news_values - exactly five objects, in this order: impact, timeliness, prominence, novelty, proximity. Each: value - that word; verdict - yes, partly or no; why - one sentence grounded in the brief.
  5. strengthen - when strength is workable or weak, one to four short strings saying how to strengthen the angle from what the organizer could add; [] when strong.
  6. headlines - 5 to 10 objects, each hook (exactly one of: data, question, bold claim, contrast, human interest, urgency, counterintuitive) and text (a headline in sentence case). Use at least three different hooks.
  7. missing - one short string per required question the facts list as missing, in that order; [] when none.
  8. caveats - at most 4 short strings; [] when there is nothing to say.
{
  "task": "angle",
  "summary": "one sentence",
  "angle": "one sentence",
  "strength": "workable",
  "news_values": [ { "value": "impact", "verdict": "yes", "why": "one sentence" } ],
  "strengthen": [ "a short string" ],
  "headlines": [ { "hook": "data", "text": "a headline" } ],
  "missing": [ "a short string" ],
  "caveats": [ "a short string" ]
}

The page holds it to its own facts (check() in pressreply.js; any warning makes the reply flagged): strength is strong, workable or weak - strong with at least two news values answered yes, weak with fewer than three; exactly the five news values in order, each yes, partly or no; strengthen is not empty unless the angle is strong; 5-10 headlines, each hook from the list, at least three different hooks, none in Title Case, none with a banned phrase; no number in a headline, the angle or the summary that the input does not hold; and as many missing lines as the brief has unanswered required questions.

draft

Write the press release in the universal structure, holding every rule above.

  1. designation - the facts' designation, exactly.
  2. headline - the chosen headline exactly when the facts give one; otherwise your own, in sentence case.
  3. subheadline - about 20 words with a secondary angle, or "".
  4. dateline - the facts' dateline, exactly.
  5. lead - the lead after the dateline (do not repeat the dateline): 25-35 words, answering who, what, when, where, why and how. Count the words.
  6. paragraphs - the body in order, one string per paragraph: body 1 with the primary data point, then the spokesperson's quote paragraph, then context, then the second quote paragraph only when the facts name a second quote, then availability or next steps. Each quote paragraph carries one quote in straight double quotes, written from what the brief says that quote should say, attributed with "said" and the person's full name and title. When that message is empty enthusiasm or uses a banned phrase, keep only the substance it carries; when it carries none, write one plain factual sentence and say in the angle note that the quote needs a real message. Cover the type's mandatory elements the brief gives. With the headline, subheadline, lead and boilerplate, the release runs 300-500 words.
  7. boilerplate_heading - "About " and the company name.
  8. boilerplate - as the facts say: copied exactly, trimmed under 100 words, or written from the brief's company facts under 100 words. Factual, no superlatives.
  9. contact - the media contact as the facts say.
  10. end_mark - "###".
  11. angle_note - one or two sentences: why this angle; when the facts say a quote, the boilerplate or a mandatory element is missing, say so.
  12. next_steps - an object: distribution - one or two sentences that copy the facts' send window and, when the release day is outside it, name the next day in the window; pitch - one sentence offering a journalist email pitch with subject-line variants; social - one sentence on a social teaser; shortlist - one sentence on how to build the journalist shortlist from the brief's target outlets.
{
  "task": "draft",
  "designation": "the facts' designation",
  "headline": "a headline",
  "subheadline": "",
  "dateline": "the facts' dateline",
  "lead": "25-35 words",
  "paragraphs": [ "a paragraph" ],
  "boilerplate_heading": "About Company",
  "boilerplate": "under 100 words",
  "contact": "the media contact",
  "end_mark": "###",
  "angle_note": "one or two sentences",
  "next_steps": { "distribution": "one or two sentences", "pitch": "one sentence", "social": "one sentence", "shortlist": "one sentence" }
}

The page assembles the reply into a release and runs its own linter over it: the designation and the dateline exactly as the page wrote them; the chosen headline unchanged; every linter check met (the 25-35 word lead, 300-500 words from headline to boilerplate, no banned phrase, "said", third person outside quotes, the boilerplate, the contact, ###); no number the input does not hold; the spokesperson quoted by full name, the second speaker only when the brief names one; a boilerplate given under 100 words copied exactly; the contact email kept; the next day in the send window named when the release day falls outside it; and an angle note.

review

Hold the pasted release to the quality bar and say exactly what to change.

  1. summary - one sentence, at most 40 words: the verdict and the most important fix.
  2. verdict - exactly ready to send, fix first or rewrite. Never milder than the page's verdict in the facts (ready to send is milder than fix first, which is milder than rewrite). Use rewrite when the release has no genuine news or its lead is not news.
  3. checks - one object per check row in the facts, in the facts' order, every row: id - the row's id exactly; status - met or not met: copy every status the facts give as met or not met, and decide every row the facts give as unclear or for review; note - one sentence; for a row you decided, say why.
  4. edits - at most 12 objects, the most important first: find - text copied verbatim from the release, long enough to be unique; replace - the corrected text, holding every house rule; why - one short sentence naming the rule. A rewritten quote is a suggestion for the speaker to approve - say so in why. [] only when the verdict is ready to send.
  5. headline - the headline you recommend, in sentence case; the release's own when it already holds.
  6. lead - the lead you recommend after the dateline, 25-35 words, using only facts in the release and the brief.
  7. caveats - at most 4 short strings; [] when there is nothing to say.
{
  "task": "review",
  "summary": "one sentence",
  "verdict": "fix first",
  "checks": [ { "id": "designation", "status": "met", "note": "one sentence" } ],
  "edits": [ { "find": "verbatim text", "replace": "corrected text", "why": "one short sentence" } ],
  "headline": "a headline",
  "lead": "25-35 words",
  "caveats": [ "a short string" ]
}

The page requires a verdict no milder than its own linter's; one check per row it sent, in its order, with the same id, each met or not met, and every status it gave as met or not met copied; edits unless the verdict is ready to send, every find found verbatim in the release, no banned phrase in a replacement; a recommended lead of 25-35 words and a headline not in Title Case; and no number neither the release nor the brief holds. It then applies every edit, re-runs its linter, and flags any check the edits break that held before.

Worked examples - one per lane

Three runs from the page's four free samples (fictional companies, people, figures and contacts). Each input is exactly what the page sends; each reply is the saved reply the sample replays, shipped unedited; the last line is the page's own check.

angle - Product launch, US - draft breaks five rules

The brief: ready to draft (10 of 10 required questions answered); type: Product launch; market: United States; designation: FOR IMMEDIATE RELEASE; dateline: AUSTIN, Texas (Nov. 17, 2026) --; the pasted release: fix first.

Input:

{
 "task": "angle",
 "brief": "Company: Ferncount\nWhat it does: Ferncount makes accounts payable software for mid-size distributors.\nHeadquarters: Austin, Texas\nRelease type: Product launch\nThe other party (partner, investor, target or award body): not given\nThe news: Ferncount today launched Match, a module that reconciles supplier invoices against purchase orders and warehouse receipts automatically and routes only the mismatches to an accounts payable clerk.\nWhy now: Distributors close their books late every month because three-way matching is still done by hand; Match is generally available from today after a six-month pilot.\nTarget journalists and outlets: Supply chain and finance trade press (accounts payable, distribution and ERP beats); the Austin business desk\nTarget market: United States\nMedia format: Digital and wire\nLanguage: English\nDateline city: Austin (Texas)\nRelease date: 2026-11-17\nEmbargo: none - for immediate release\nSpokesperson: Dana Ruiz, chief executive officer of Ferncount\nWhat the spokesperson's quote should say: Three-way matching fails on partial deliveries, not on clean invoices - Match was built around the messy 8% and leaves the clean ones alone.\nSecond quote from: Priya Kalvantri, controller at Westbank Supply\nWhat the second quote should say: During the pilot the team stopped working weekends at month end; the clerks now only see invoices that actually disagree.\nData points:\n- Pilot with 14 mid-size distributors from May to October 2026\n- Match reconciled 92% of 61,000 pilot invoices without a person touching them\n- Month-end close at pilot customers fell from 9 days to 4 days\n- Accounts payable teams at pilot customers spent 31% fewer hours on matching\nAvailability, pricing and call to action: Available from Nov. 17, 2026 to Ferncount customers in the US and Canada at $400 per month per entity; 30-day free trial at ferncount.example/match\nBoilerplate as given: Ferncount makes accounts payable software for mid-size distributors. Founded in 2019 and based in Austin, Texas, the company serves 380 distributors across the United States and Canada.\nMedia contact: Leah Okafor, press@ferncount.example, +1 512 555 0142",
 "headline": "",
 "draft": "",
 "facts": "Brief: 10 of 10 required questions answered.\nRelease type: Product launch. News angle question: What problem does this solve that could not be solved before? What is genuinely new?\nmust: the template's mandatory elements, in order of importance - product name and what it does, in one sentence; specific pricing and availability (date, regions, channels) - never \"competitive pricing\"; the problem it solves, quantified if possible; 3-5 key differentiators; a customer or beta tester quote if available. An element the brief does not give is left out, never invented.\nMarket: United States - style guide: AP Stylebook.\nmust: AP style - sentence-case headline; numerals for 10 and up, one through nine spelled out; \"percent\" not \"%\"; a.m. and p.m.; abbreviate Jan., Feb., Aug., Sept., Oct., Nov., Dec. before a date; no Oxford comma.\nNumbers in the brief: 14, 2026, 92, 61000, 9, 4, 31, 17, 400, 30, 8, 2019, 380, 11, 1, 512, 555, 142.\nmust: 5 to 10 headlines; every hook from this list - data, question, bold claim, contrast, human interest, urgency, counterintuitive - and at least 3 different hooks; sentence case; no banned phrase; every number in a headline appears in the brief."
}

Reply:

{
 "task": "angle",
 "summary": "Strong angle: a generally available module that cut pilot month-end close from 9 days to 4 days, backed by pilot data and a customer voice - ready to draft.",
 "angle": "Ferncount's Match, generally available from Nov. 17, 2026, automates three-way invoice matching for mid-size distributors and cut month-end close at 14 pilot customers from 9 days to 4 days.",
 "strength": "strong",
 "news_values": [
  {
   "value": "impact",
   "verdict": "yes",
   "why": "Pilot customers closed their books in 4 days instead of 9 and spent 31 percent fewer hours on matching."
  },
  {
   "value": "timeliness",
   "verdict": "yes",
   "why": "Match becomes generally available on Nov. 17, 2026, right after a six-month pilot that ended in October."
  },
  {
   "value": "prominence",
   "verdict": "partly",
   "why": "Ferncount serves 380 distributors, but neither the company nor Westbank Supply is a household name outside the trade."
  },
  {
   "value": "novelty",
   "verdict": "yes",
   "why": "Three-way matching is still done by hand at most distributors, and Match routes only the mismatches to a clerk."
  },
  {
   "value": "proximity",
   "verdict": "partly",
   "why": "The Austin business desk has a local company, and trade press covering US and Canadian distribution has a direct audience."
  }
 ],
 "strengthen": [],
 "headlines": [
  {
   "hook": "data",
   "text": "Ferncount's Match cuts distributor month-end close from 9 days to 4"
  },
  {
   "hook": "data",
   "text": "Match reconciled 92 percent of 61,000 pilot invoices without a person touching them"
  },
  {
   "hook": "question",
   "text": "Why do distributors still close their books late every month?"
  },
  {
   "hook": "contrast",
   "text": "Clean invoices pass, mismatches go to a clerk: Ferncount launches Match"
  },
  {
   "hook": "human interest",
   "text": "Accounts payable clerks at Westbank Supply stop working weekends at month end"
  },
  {
   "hook": "counterintuitive",
   "text": "Three-way matching fails on partial deliveries, not clean invoices, says Ferncount"
  },
  {
   "hook": "urgency",
   "text": "Ferncount's Match is available today with a 30-day free trial"
  }
 ],
 "missing": [],
 "caveats": [
  "Match is a common word; pair it with Ferncount in the headline so it is searchable.",
  "AP style writes 92 percent, not 92%, and Nov. 17 with the month abbreviated."
 ]
}

The page's check: kept - nothing to flag

draft - Series A, Germany, under embargo - draft holds

The brief: ready to draft (10 of 10 required questions answered); type: Funding round; market: Germany, Austria and Switzerland; designation: EMBARGOED UNTIL 07:00 CET, Wednesday, 18 November 2026; dateline: BERLIN, 18 November 2026 --; the pasted release: ready to send.

Input:

{
 "task": "draft",
 "brief": "Company: Voltrenn Labs\nWhat it does: Voltrenn Labs builds load-forecasting software for municipal utilities.\nHeadquarters: Berlin, Germany\nRelease type: Funding round\nThe other party (partner, investor, target or award body): Halden Ventures (lead investor)\nThe news: Voltrenn Labs has raised a 12 million euro Series A led by Halden Ventures to bring its load-forecasting software for municipal utilities to France and the Netherlands.\nWhy now: From January 2027 German grid operators must publish load forecasts at 15-minute intervals; Voltrenn already produces them for 41 municipal utilities.\nTarget journalists and outlets: European energy and climate-tech press, German business dailies, startup and venture press\nTarget market: Germany, Austria and Switzerland\nMedia format: All formats\nLanguage: English\nDateline city: Berlin\nRelease date: 2026-11-18\nEmbargo: 2026-11-18 07:00 CET\nSpokesperson: Jonas Weber, co-founder and chief executive officer of Voltrenn Labs\nWhat the spokesperson's quote should say: Municipal utilities do not lack data, they lack the hours to turn it into a forecast the regulator accepts - and that gap exists in every market we are entering.\nSecond quote from: Marta Lindqvist, partner at Halden Ventures\nWhat the second quote should say: The 2027 forecasting rule turns a nice-to-have into a compliance deadline, and Voltrenn is already running at 41 utilities.\nData points:\n- 12 million euro Series A led by Halden Ventures, with existing investor Ostwerk Capital\n- Total funding to date: 15.5 million euro\n- 41 municipal utilities in Germany use Voltrenn, up from 9 a year ago\n- Average forecast error of 2.8% at the 15-minute interval\n- Team to grow from 34 to 60 people by the end of 2027\nAvailability, pricing and call to action: Offices opening in Lyon and Utrecht in the first half of 2027\nBoilerplate as given: Voltrenn Labs builds load-forecasting software for municipal utilities. Founded in 2021 and based in Berlin, the company forecasts electricity demand at 15-minute intervals for 41 utilities in Germany.\nMedia contact: Anke Vogel, press@voltrenn.example, +49 30 5550 1834",
 "headline": "",
 "draft": "",
 "facts": "Designation: EMBARGOED UNTIL 07:00 CET, Wednesday, 18 November 2026\nDateline: BERLIN, 18 November 2026 --\nHeadline: none chosen - write one in sentence case.\nRelease type: Funding round. News angle question: What will this money enable? The funding is the hook; the story is what comes next.\nmust: the template's mandatory elements, in order of importance - amount raised, round type, lead investor and use of funds - all in the first paragraph; an investor quote explaining the thesis; total funding to date; key company metrics (ARR, users, growth rate); specific hiring plans or expansion targets. An element the brief does not give is left out, never invented.\nMarket: Germany, Austria and Switzerland - style guide: dpa style (formal; marketing language is out).\nmust: sentence-case headline; formal, informational tone - no promotional language.\nLead: 25-35 words - count them. The release from headline to boilerplate: 300-500 words.\nSpokesperson: Jonas Weber, co-founder and chief executive officer of Voltrenn Labs - full name and title on first reference, last name after.\nSecond quote: Marta Lindqvist, partner at Halden Ventures.\nBoilerplate: given, 28 words - copy it exactly.\nMedia contact: Anke Vogel, press@voltrenn.example, +49 30 5550 1834 - copy it exactly.\nSend window: Tue-Thu, 10:00-12:00 CET; avoid bridge days around holidays, Karneval week in the Rhineland. The release date is a Wednesday, inside the window.\nEmbargoed: it goes to journalists under embargo ahead of the lift, so they can prepare; the window applies to the day the embargo lifts.\nNumbers in the brief: 12, 2027, 15, 41, 15.5, 9, 2.8, 34, 60, 2021, 2026, 11, 18, 7, 0, 49, 30, 5550, 1834."
}

Reply:

{
 "task": "draft",
 "designation": "EMBARGOED UNTIL 07:00 CET, Wednesday, 18 November 2026",
 "headline": "Voltrenn Labs raises 12 million euro to take utility load forecasting to France and the Netherlands",
 "subheadline": "Series A led by Halden Ventures follows growth from 9 to 41 German municipal utilities ahead of a 2027 forecasting rule",
 "dateline": "BERLIN, 18 November 2026 --",
 "lead": "Voltrenn Labs, a Berlin maker of load-forecasting software for municipal utilities, has raised a 12 million euro Series A led by Halden Ventures to expand into France and the Netherlands.",
 "paragraphs": [
  "Existing investor Ostwerk Capital also took part in the round, which brings total funding to date to 15.5 million euro. Voltrenn Labs forecasts electricity demand at 15-minute intervals for 41 municipal utilities in Germany, up from 9 a year ago, with an average forecast error of 2.8 per cent at the 15-minute interval.",
  "\"Municipal utilities do not lack data, they lack the hours to turn it into a forecast the regulator accepts,\" said Jonas Weber, co-founder and chief executive officer of Voltrenn Labs. \"That gap exists in every market we are entering.\"",
  "From January 2027, German grid operators must publish load forecasts at 15-minute intervals. Voltrenn Labs already produces forecasts at that interval for its 41 utility customers in Germany. The Series A will bring the same software to municipal utilities in France and the Netherlands, starting with new offices in Lyon and Utrecht.",
  "\"The 2027 forecasting rule turns a nice-to-have into a compliance deadline, and Voltrenn is already running at 41 utilities,\" said Marta Lindqvist, partner at Halden Ventures.",
  "Voltrenn Labs will open the Lyon and Utrecht offices in the first half of 2027. To staff that expansion, the company plans to grow its team from 34 to 60 people by the end of 2027."
 ],
 "boilerplate_heading": "About Voltrenn Labs",
 "boilerplate": "Voltrenn Labs builds load-forecasting software for municipal utilities. Founded in 2021 and based in Berlin, the company forecasts electricity demand at 15-minute intervals for 41 utilities in Germany.",
 "contact": "Anke Vogel, press@voltrenn.example, +49 30 5550 1834",
 "end_mark": "###",
 "angle_note": "The funding is the hook, but the story is what it enables: expansion into France and the Netherlands by a company already meeting a 2027 German forecasting rule at 41 utilities. The brief gives no revenue or ARR figure, so the release uses utility count and forecast accuracy as its company metrics.",
 "next_steps": {
  "distribution": "Send to journalists under embargo before it lifts at 07:00 CET on Wednesday, 18 November 2026, which is inside the send window: Tue-Thu, 10:00-12:00 CET; avoid bridge days around holidays and Karneval week in the Rhineland.",
  "pitch": "An embargoed email pitch to energy and climate-tech reporters can offer the 2027 compliance deadline as the news peg, with subject-line variants built on the funding, the regulation and the expansion.",
  "social": "A social teaser after the embargo lifts can pair the 12 million euro Series A with the growth from 9 to 41 utilities.",
  "shortlist": "Build the shortlist from European energy and climate-tech reporters, German business dailies and startup and venture press, prioritising those who have covered grid regulation."
 }
}

The release as the page assembles it from the reply:

EMBARGOED UNTIL 07:00 CET, Wednesday, 18 November 2026

Voltrenn Labs raises 12 million euro to take utility load forecasting to France and the Netherlands
Series A led by Halden Ventures follows growth from 9 to 41 German municipal utilities ahead of a 2027 forecasting rule

BERLIN, 18 November 2026 -- Voltrenn Labs, a Berlin maker of load-forecasting software for municipal utilities, has raised a 12 million euro Series A led by Halden Ventures to expand into France and the Netherlands.

Existing investor Ostwerk Capital also took part in the round, which brings total funding to date to 15.5 million euro. Voltrenn Labs forecasts electricity demand at 15-minute intervals for 41 municipal utilities in Germany, up from 9 a year ago, with an average forecast error of 2.8 per cent at the 15-minute interval.

"Municipal utilities do not lack data, they lack the hours to turn it into a forecast the regulator accepts," said Jonas Weber, co-founder and chief executive officer of Voltrenn Labs. "That gap exists in every market we are entering."

From January 2027, German grid operators must publish load forecasts at 15-minute intervals. Voltrenn Labs already produces forecasts at that interval for its 41 utility customers in Germany. The Series A will bring the same software to municipal utilities in France and the Netherlands, starting with new offices in Lyon and Utrecht.

"The 2027 forecasting rule turns a nice-to-have into a compliance deadline, and Voltrenn is already running at 41 utilities," said Marta Lindqvist, partner at Halden Ventures.

Voltrenn Labs will open the Lyon and Utrecht offices in the first half of 2027. To staff that expansion, the company plans to grow its team from 34 to 60 people by the end of 2027.

About Voltrenn Labs
Voltrenn Labs builds load-forecasting software for municipal utilities. Founded in 2021 and based in Berlin, the company forecasts electricity demand at 15-minute intervals for 41 utilities in Germany.

Media contact
Anke Vogel, press@voltrenn.example, +49 30 5550 1834

###

The page's check: kept - The page's linter passes the drafted release: 30 words in the lead, 301 in all, 28 words of boilerplate.

review - Product launch, US - draft breaks five rules

The brief: ready to draft (10 of 10 required questions answered); type: Product launch; market: United States; designation: FOR IMMEDIATE RELEASE; dateline: AUSTIN, Texas (Nov. 17, 2026) --; the pasted release: fix first.

Input:

{
 "task": "review",
 "brief": "Company: Ferncount\nWhat it does: Ferncount makes accounts payable software for mid-size distributors.\nHeadquarters: Austin, Texas\nRelease type: Product launch\nThe other party (partner, investor, target or award body): not given\nThe news: Ferncount today launched Match, a module that reconciles supplier invoices against purchase orders and warehouse receipts automatically and routes only the mismatches to an accounts payable clerk.\nWhy now: Distributors close their books late every month because three-way matching is still done by hand; Match is generally available from today after a six-month pilot.\nTarget journalists and outlets: Supply chain and finance trade press (accounts payable, distribution and ERP beats); the Austin business desk\nTarget market: United States\nMedia format: Digital and wire\nLanguage: English\nDateline city: Austin (Texas)\nRelease date: 2026-11-17\nEmbargo: none - for immediate release\nSpokesperson: Dana Ruiz, chief executive officer of Ferncount\nWhat the spokesperson's quote should say: Three-way matching fails on partial deliveries, not on clean invoices - Match was built around the messy 8% and leaves the clean ones alone.\nSecond quote from: Priya Kalvantri, controller at Westbank Supply\nWhat the second quote should say: During the pilot the team stopped working weekends at month end; the clerks now only see invoices that actually disagree.\nData points:\n- Pilot with 14 mid-size distributors from May to October 2026\n- Match reconciled 92% of 61,000 pilot invoices without a person touching them\n- Month-end close at pilot customers fell from 9 days to 4 days\n- Accounts payable teams at pilot customers spent 31% fewer hours on matching\nAvailability, pricing and call to action: Available from Nov. 17, 2026 to Ferncount customers in the US and Canada at $400 per month per entity; 30-day free trial at ferncount.example/match\nBoilerplate as given: Ferncount makes accounts payable software for mid-size distributors. Founded in 2019 and based in Austin, Texas, the company serves 380 distributors across the United States and Canada.\nMedia contact: Leah Okafor, press@ferncount.example, +1 512 555 0142",
 "headline": "",
 "draft": "FOR IMMEDIATE RELEASE\n\nFerncount Launches Match, An Innovative New Way To Reconcile Invoices\n\nAUSTIN, Texas (Nov. 17, 2026) -- Ferncount, the Austin company that makes accounts payable software for mid-size distributors, today launched Match, a module that reconciles supplier invoices against purchase orders and warehouse receipts automatically and sends only the mismatches to a clerk for review.\n\nDistributors still match most supplier invoices by hand. Partial deliveries, split shipments and price changes mean an invoice rarely lines up with one purchase order and one receipt, so accounts payable teams spend the last week of every month checking paperwork line by line, and the books close late.\n\nMatch reads each invoice, finds the purchase order lines and warehouse receipts it belongs to, and settles every line that agrees. Lines that disagree go to a clerk with the difference already worked out: a short delivery, a price change, or a duplicate. During a pilot with 14 mid-size distributors from May to October 2026, Match reconciled 92% of 61,000 invoices without a person touching them.\n\n\"We are thrilled to bring Match to our customers,\" stated Dana Ruiz, chief executive officer of Ferncount. \"Three-way matching fails on partial deliveries, not on clean invoices, so we built Match around the messy 8% and left the clean ones alone.\"\n\nAt pilot customers, month-end close fell from nine days to four, and accounts payable teams spent 31% fewer hours on matching.\n\n\"During the pilot the team stopped working weekends at month end,\" said Priya Kalvantri, controller at Westbank Supply. \"The clerks now only see invoices that actually disagree.\"\n\nMatch is available from Nov. 17, 2026 to Ferncount customers in the US and Canada at $400 per month per entity. A 30-day free trial is available at ferncount.example/match.\n\nAbout Ferncount\nFerncount makes accounts payable software for mid-size distributors. Founded in 2019 and based in Austin, Texas, the company serves 380 distributors across the United States and Canada.\n\nMedia contact\nLeah Okafor, press@ferncount.example, +1 512 555 0142\n\n###",
 "facts": "The page's check of the pasted release (38 words in the lead, 308 from headline to boilerplate, 27 words of boilerplate, 2 quotes). Verdict: fix first.\n1. designation | met | \"FOR IMMEDIATE RELEASE\"\n2. headline | not met | reads as Title Case (4 of 4 longer common words capitalized) - capitalize only the first word and proper nouns\n3. dateline | met | \"AUSTIN, Texas (Nov. 17, 2026) --\"\n4. lead | not met | 38 words - over 35 buries the news\n5. length | met | 308 words\n6. newsfirst | for review | \"Ferncount, the Austin company that makes accounts payable software for mid-size distributors, today launched Match, a module that reconciles...\"\n7. pyramid | for review | 6 body paragraphs\n8. third | met | none outside quotes\n9. active | met | 0 of 9 sentences read as passive\n10. superlatives | met | none found\n11. banned | not met | \"thrilled\", \"innovative\"\n12. said | not met | attributed with \"stated\" - use \"said\"\n13. number | met | 7 numbers in the lead and body\n14. quotes | not met | empty enthusiasm: \"We are thrilled to bring Match to our customers,\"\n15. boilerplate | met | 27 words\n16. contact | met | given\n17. endmark | met | \"###\"\n18. style | unclear | AP writes \"percent\", not \"%\"\nmust: one check row per line above, in this order, with the same id. Copy every status that reads met or not met exactly; decide every row that reads unclear or for review as met or not met, and say why.\nExpected designation: FOR IMMEDIATE RELEASE\nExpected dateline: AUSTIN, Texas (Nov. 17, 2026) --\nMarket: United States - style guide: AP Stylebook.\nmust: AP style - sentence-case headline; numerals for 10 and up, one through nine spelled out; \"percent\" not \"%\"; a.m. and p.m.; abbreviate Jan., Feb., Aug., Sept., Oct., Nov., Dec. before a date; no Oxford comma."
}

Reply:

{
 "task": "review",
 "summary": "Fix first: the facts and data hold, but the quote must go - cut \"thrilled\" and \"stated\" and let Dana Ruiz explain why partial deliveries break three-way matching.",
 "verdict": "fix first",
 "checks": [
  {
   "id": "designation",
   "status": "met",
   "note": "FOR IMMEDIATE RELEASE sits at the top as expected."
  },
  {
   "id": "headline",
   "status": "not met",
   "note": "The headline is in Title Case and carries the banned word \"innovative\"."
  },
  {
   "id": "dateline",
   "status": "met",
   "note": "The dateline matches the expected AP form."
  },
  {
   "id": "lead",
   "status": "not met",
   "note": "At 38 words the lead runs past 35 and spends its opening on the company description."
  },
  {
   "id": "length",
   "status": "met",
   "note": "At 308 words the release is inside the 300-500 range."
  },
  {
   "id": "newsfirst",
   "status": "met",
   "note": "Decided met: the lead names the company, the launch of Match and what it does in its first sentence."
  },
  {
   "id": "pyramid",
   "status": "not met",
   "note": "Decided not met: the first body paragraph is background on manual matching, while the primary data point, 92% of 61,000 pilot invoices, waits in the next paragraph."
  },
  {
   "id": "third",
   "status": "met",
   "note": "No first or second person appears outside the quotes."
  },
  {
   "id": "active",
   "status": "met",
   "note": "No sentence reads as passive."
  },
  {
   "id": "superlatives",
   "status": "met",
   "note": "No superlatives were found."
  },
  {
   "id": "banned",
   "status": "not met",
   "note": "\"Thrilled\" appears in the quote and \"innovative\" in the headline."
  },
  {
   "id": "said",
   "status": "not met",
   "note": "Dana Ruiz is attributed with \"stated\" instead of \"said\"."
  },
  {
   "id": "number",
   "status": "met",
   "note": "The lead and body carry pilot, invoice, close-time, hours and price figures."
  },
  {
   "id": "quotes",
   "status": "not met",
   "note": "The first quote opens with empty enthusiasm before reaching its insight on partial deliveries."
  },
  {
   "id": "boilerplate",
   "status": "met",
   "note": "At 27 words the boilerplate is factual and under 100 words."
  },
  {
   "id": "contact",
   "status": "met",
   "note": "Leah Okafor's email and phone are given."
  },
  {
   "id": "endmark",
   "status": "met",
   "note": "The release ends with ###."
  },
  {
   "id": "style",
   "status": "not met",
   "note": "Decided not met: the release writes 92%, 8% and 31% where AP writes percent, and uses an Oxford comma before \"or a duplicate\"."
  }
 ],
 "edits": [
  {
   "find": "\"We are thrilled to bring Match to our customers,\" stated Dana Ruiz, chief executive officer of Ferncount. \"Three-way matching fails on partial deliveries, not on clean invoices, so we built Match around the messy 8% and left the clean ones alone.\"",
   "replace": "\"Three-way matching fails on partial deliveries, not on clean invoices,\" said Dana Ruiz, chief executive officer of Ferncount. \"Match was built around the messy 8 percent and leaves the clean ones alone.\"",
   "why": "Removes the banned \"thrilled\" and the empty enthusiasm and attributes with \"said\"; a suggested quote for Dana Ruiz to approve."
  },
  {
   "find": "Ferncount Launches Match, An Innovative New Way To Reconcile Invoices",
   "replace": "Ferncount launches Match to reconcile distributor invoices automatically",
   "why": "Sentence case and no banned word \"innovative\"."
  },
  {
   "find": "Ferncount, the Austin company that makes accounts payable software for mid-size distributors, today launched Match, a module that reconciles supplier invoices against purchase orders and warehouse receipts automatically and sends only the mismatches to a clerk for review.",
   "replace": "Ferncount today launched Match, which reconciles distributors' supplier invoices against purchase orders and warehouse receipts automatically and routes only mismatches to a clerk, cutting month-end close at pilot customers from nine days to four.",
   "why": "The lead must answer who, what and why in 25-35 words with the strongest result up front."
  },
  {
   "find": "Distributors still match most supplier invoices by hand. Partial deliveries, split shipments and price changes mean an invoice rarely lines up with one purchase order and one receipt, so accounts payable teams spend the last week of every month checking paperwork line by line, and the books close late.\n\nMatch reads each invoice, finds the purchase order lines and warehouse receipts it belongs to, and settles every line that agrees. Lines that disagree go to a clerk with the difference already worked out: a short delivery, a price change, or a duplicate. During a pilot with 14 mid-size distributors from May to October 2026, Match reconciled 92% of 61,000 invoices without a person touching them.",
   "replace": "Match reads each invoice, finds the purchase order lines and warehouse receipts it belongs to, and settles every line that agrees. Lines that disagree go to a clerk with the difference already worked out: a short delivery, a price change or a duplicate. During a pilot with 14 mid-size distributors from May to October 2026, Match reconciled 92 percent of 61,000 invoices without a person touching them.\n\nDistributors still match most supplier invoices by hand. Partial deliveries, split shipments and price changes mean an invoice rarely lines up with one purchase order and one receipt, so accounts payable teams spend the last week of every month checking paperwork line by line, and the books close late.",
   "why": "Inverted pyramid: the primary data point comes in the first body paragraph, before the background; AP writes percent and drops the Oxford comma."
  },
  {
   "find": "Match is available from Nov. 17, 2026 to Ferncount customers",
   "replace": "After a six-month pilot, Match is generally available from Nov. 17, 2026 to Ferncount customers",
   "why": "Availability should say the module is generally available after the six-month pilot."
  },
  {
   "find": "spent 31% fewer hours",
   "replace": "spent 31 percent fewer hours",
   "why": "AP style writes percent, not %."
  }
 ],
 "headline": "Ferncount launches Match to reconcile distributor invoices automatically",
 "lead": "Ferncount today launched Match, which reconciles distributors' supplier invoices against purchase orders and warehouse receipts automatically and routes only mismatches to a clerk, cutting month-end close at pilot customers from nine days to four.",
 "caveats": [
  "The rewritten Dana Ruiz quote keeps the message planned for it; it still needs her approval before sending."
 ]
}

The page's check: kept - With every edit applied, the page's linter reads ready to send (0 checks not met, was 5).

The free release skeleton for the award sample

What the page writes before any run: the universal structure, filled with what it knows, every bracket still to be written.

FOR IMMEDIATE RELEASE

[Headline - sentence case, the core news]

[Subheadline - optional, about 20 words, a secondary angle]

LONDON, 20 November 2026 -- [Lead - who, what, when, where, why and how in 25-35 words]

[Body 1 - expand on the lead; the primary data point]

"[Quote - insight, not enthusiasm]" said Tamsin Clewer of Brightwell Dental.

[Body 2 - context and market data]

[Body 3 - availability, future plans, call to action]

About Brightwell Dental
[About 100 words. Factual. No superlatives.]

Media contact
Tamsin Clewer | hello@brightwell.example

###

<!-- Award - mandatory elements:
  - award name and granting organization
  - why it was given (criteria or category)
  - what makes it selective or significant
  - a quote from the granting body if available
-->

Build the input yourself

Load the engine in node (global.window = global; require("./presskit.js"); require("./pressreply.js")), then:

const K = PressKit, R = PressReply;
const f = K.form(Object.assign(K.blank(), { company: "Acme Robotics", about: "Acme Robotics builds warehouse picking robots.", hq: "Denver, Colorado",
  type: "launch", news: "Acme Robotics today launched Picker 2, a warehouse robot that picks mixed-size parcels from shared shelves.",
  whyNow: "Peak season starts next month.", audience: "Logistics trade press", market: "us", city: "Denver", region: "Colo.", date: "2027-03-02",
  spokesName: "Ana Silva", spokesTitle: "chief executive officer of Acme Robotics", spokesQuote: "Picking, not driving, is the slow part of a warehouse.",
  data: "Picks 600 parcels an hour", contactName: "Ben Ito", contactEmail: "press@acme.example" }));
// f.rows (the ten questions), f.verdict, f.desig, f.dl, f.send, f.findings - and f.lint when f.draft holds a pasted release
K.skeletonMd(f); K.board(f)                                  // the free exports
const b = K.buildInput(f, "angle");                          // or "draft" (set f.headline) or "review" (set f.draft)
const wire = K.toWire(b.input);                              // POST this to /estimate and /run
// then: const reply = R.normalize(R.parseReply(job.output.output), "angle");
// R.check(reply, b)                                         // {status: kept or flagged, notes}
// R.assemble(reply)                                         // a draft as release text; R.applyEdits(text, reply.edits) for a review

Get a token for the steps below from /tokens.html.

Step 1 — a tiny client helper

One function that sends JSON and unwraps the response. Paste a personal token from /tokens.html, or leave it empty and mint a guest token in step 2.

BASE="https://api.skillsafe.ai/v1/app-api"
TOKEN="YOUR_TOKEN"   # from https://wire-ready.skillsafe.ai/tokens.html
api() { # api METHOD PATH [JSON-BODY]
  curl -s -X "$1" "$BASE$2" -H "Content-Type: application/json" \
    ${TOKEN:+-H "Authorization: Bearer $TOKEN"} ${3:+--data "$3"}
}

Step 2 — a token

A guest token is enough for /me and /estimate. A run is metered, so it needs a personal token: sign in on /tokens.html and copy it from there.

# a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
TOKEN=$(curl -s -X POST "$BASE/guest" -H "Content-Type: application/json" -d '{"slug":"wire-ready"}' | jq -r '.data.token')

Step 3 — GET /me

Who the token is (subject_type: user or guest) and the credit balance.

api GET /me | jq '.data | {subject_type, credits}' 

Step 4 — POST /estimate

Free. The body is the run input itself, the bare object (never wrapped in {"input": ...}). hold_credits is a reservation, not the price; min_credits is what the balance must cover; model_alias reads gpt-terra.

# input.json: the run input object - {"task": "angle", "brief": "Company: ...\nThe news: ...", "headline": "", "draft": "", "facts": "Brief: 10 of 10 required questions answered. ..."}
# - see the input table
api POST /estimate "$(cat input.json)" | jq '.data | {hold_credits, min_credits, model, model_alias, markup_bps, warnings}' 

Step 5 — POST /run, then poll the job

Send an Idempotency-Key built from the lane and the input: a retry with the same key never bills twice. The page uses wire-ready:<task>:<inputHash>:a<attempt> - the lane is part of the key, retry_note is left out of the hash - and its one automatic reformat retry is a new attempt number, named in the page as one extra run. An angle carries summary, angle, strength, news_values, strengthen, headlines, missing and caveats; a draft carries designation, headline, subheadline, dateline, lead, paragraphs, the boilerplate, contact, end_mark, angle_note and next_steps; a review carries summary, verdict, checks, edits, headline, lead and caveats. The code below prints the headline of any of them: the angle's strength and headlines, the draft's headline and lead, or the review's verdict and edit count.

KEY="wire-ready:$(jq -r .task input.json):$(shasum -a 256 input.json | cut -c1-16):a1"
JOB=$(curl -s -X POST "$BASE/run" -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $KEY" --data @input.json | jq -r '.data.job_id')
while :; do
  J=$(api GET "/jobs/$JOB"); S=$(echo "$J" | jq -r '.data.status')
  case "$S" in succeeded|failed|cancelled) break;; esac; sleep 2
done
echo "$J" | jq -r '.data.output.output' > reply.json   # one JSON object, the reply contract
echo "$J" | jq '.data | {charged_credits, truncated}'
jq -r 'if .task == "angle" then .strength, (.headlines[] | "- \(.text)")
       elif .task == "draft" then .headline, .lead
       else .verdict, "\(.edits | length) edits" end' reply.json

Step 6 — POST /run-stream

The same run as Server-Sent Events, with the same input.json. Browsers receive progress ticks rather than text deltas; the final done event carries the reply.

# Server-Sent Events: tick/delta events while the job runs, then a final event with the job
curl -N -s -X POST "$BASE/run-stream" -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: wire-ready:$(jq -r .task input.json):$(shasum -a 256 input.json | cut -c1-16):a1" --data @input.json