← CFP Blueprint
API
Tokens

Run CFP Blueprint from your own code

Both metered lanes are available over HTTP and each returns one JSON object. The division of labour: the page checks the timeline against the sourced floor, matches the formats to the structure, reads the form depth, picks the review posture, checks the criteria against the six community-call points and keeps only confirmed benefits - all free, in cfpkit.js. The run writes the brief or the call; the page then holds the reply to its own design (cfpreply.js).

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":"cfp-blueprint"}), so no slug header is needed afterwards. Send it as Authorization: Bearer …. The run body is the input object, sent bare.

StatusCodeMeaning
400validation_errorThe body is not a JSON object, or a required key (task, event, design, facts) is missing.
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: both 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

Two lanes - brief (the CFP design brief for the organizers) and call (the public call for papers; not available when the timeline is below the floor). A missing or unknown task is answered as brief. Both lanes send the same four fields.

The input

FieldRequiredWhat
taskyesbrief or call. If it is missing or neither, do brief and set "task": "brief".
eventyesthe event, its date, the as-of date and program announcement, the team, the structure facts and last edition's numbers.
designyesthe planned dates, every format with structure and call flags, slots and form fields, the cap, the planned anonymization, the drafted criteria and the drafted benefits with their confirmation.
factsyesthe page's timeline, format, form-depth, anonymization, criteria, benefits and first-timer picks, the gates, the signals to record and every finding tagged [fix], [check] or [info].
retry_notenooptional; if present, your previous reply was unusable - follow it.

The rules the model applies

House rules

The replies

brief

  1. summary - one sentence, at most 35 words: the timeline rung, the most important fix, and the first thing to settle.
  2. timeline - pick and planned (long, standard, floor or below: the page's pick and the rung the dates make), open, close, notify (the planned dates exactly, "" when not set), note (one sentence).
  3. formats - one object per format in the page's order: format (exactly), structure and call (true or false, as the page lists them), note (one short sentence: keep, add to the call, or drop from it).
  4. form - pick and planned (minimal, standard or extended: the page's pick and the depth the drafted fields make), cap (the planned cap as a number, or null), note (one sentence).
  5. review - pick and planned (named, optin or blind: the page's pick and the posture as planned), note (one sentence: the mechanics to publish).
  6. criteria - missing (the community-pole points the page reports missing, by the page's names; [] when none), note (one sentence).
  7. benefits - state (the confirmed benefits, exactly as drafted), drop (the unconfirmed ones, exactly), note (one sentence).
  8. support - pick (examples, encouragement or mentorship, the page's pick), note (one sentence).
  9. measurement - 2 or 3 objects: metric (one of the page's signals), revision (what it would change next edition - your design).
  10. caveats - at most 4 short strings: [fix] findings first (the most urgent four when there are more), then the most important [check] findings. [] when there are none of either.
{
  "task": "brief",
  "summary": "one sentence",
  "timeline": { "pick": "standard", "planned": "standard", "open": "YYYY-MM-DD", "close": "YYYY-MM-DD", "notify": "YYYY-MM-DD", "note": "one sentence" },
  "formats": [ { "format": "Talk (30 min)", "structure": true, "call": true, "note": "one short sentence" } ],
  "form": { "pick": "standard", "planned": "standard", "cap": 3, "note": "one sentence" },
  "review": { "pick": "named", "planned": "named", "note": "one sentence" },
  "criteria": { "missing": [], "note": "one sentence" },
  "benefits": { "state": [ "Free event ticket" ], "drop": [], "note": "one sentence" },
  "support": { "pick": "examples", "note": "one sentence" },
  "measurement": [ { "metric": "a signal", "revision": "what it changes" } ],
  "caveats": [ "a caveat" ]
}

The page holds it to its own design: the timeline, form and review picks beside the planned ones, every format with its structure and call flags, the cap, the count of missing criteria, the confirmed and dropped benefits and the first-timer pick; no date or number may appear that the input does not hold.

call

  1. title - the call's heading, naming the event.
  2. intro - two or three sentences: the event and who should submit; no figure the input does not hold.
  3. dates - exactly four objects in order: label ("Call opens", "Call closes", "Speakers hear back", "Event"), date (the planned date exactly, or "[date to set]" when not set).
  4. formats - one object per format the structure has (the page's structure formats, in order - a format only in the call is left out): format (exactly), slots (the page's count as a number, or null), submit (one sentence: what to send, from that format's fields; "[fields to set]" when it has none).
  5. cap - one sentence with the per-person cap, or "[cap to set]".
  6. review - two or three sentences: how proposals are reviewed under the page's pick; for blind review, the two phases and when identity enters ("[when identity enters]" if not stated) and the instruction to keep identifying details out of titles and text.
  7. criteria - the drafted criteria, lightly edited, one string each in order; a criterion the page flags as routing to an open space that does not exist becomes the lesson-transfer question; with no drafted criteria, [].
  8. benefits - one string per confirmed benefit, exactly what it is; nothing unconfirmed.
  9. firsttimers - one or two sentences in line with the page's first-timer pick.
  10. reserved - one sentence stating the number of slots held outside the call when the page holds some, otherwise "".
  11. contact - "[contact address]" unless the input gives one.
{
  "task": "call",
  "title": "Call for papers - an event",
  "intro": "two or three sentences",
  "dates": [ { "label": "Call opens", "date": "YYYY-MM-DD" } ],
  "formats": [ { "format": "Talk (30 min)", "slots": 18, "submit": "one sentence" } ],
  "cap": "one sentence",
  "review": "two or three sentences",
  "criteria": [ "a criterion" ],
  "benefits": [ "Free event ticket" ],
  "firsttimers": "one or two sentences",
  "reserved": "",
  "contact": "[contact address]"
}

The page requires the four dates as planned, every structure format with its slots and no format outside the structure, the cap, every drafted criterion with no routing to a missing open space, only confirmed benefits, when identity enters under blind review, and the held-slot count when the call states it.

Worked examples - every lane, every sample

These are the page's three free samples (fictional events and people; every date is illustrative). Each input is exactly what the page sends; each reply is the saved reply the sample replays, shipped as the validating model wrote it; the last line is the page's own check. Every sample has both lanes.

Mirrowmere DevOps Conference (a first community call) - brief

Dates make a long window (the page's pick: long window); 3 formats in the call; form pick extended; review pick named; 2 of 4 gates.

Input:

{
 "task": "brief",
 "event": "Event: Mirrowmere DevOps Conference 2027; event date 2027-09-23; a community conference - the call fills the program; first CFP; a compounding annual asset\nAs of: 2026-11-02 (46.4 weeks before the event); program announcement 2027-06-30\nTeam: review committee 3; mentor pool no; international speakers yes; diversity a stated goal yes; outreach capacity no; past accepted proposals to publish no\nStructure: open-space block no; fast-moving field no; slots held outside the call 0\nLast edition: no data",
 "design": "Timeline as planned: opens 2027-01-15, closes 2027-04-30, notifies 2027-05-28, event 2027-09-23 (open 15 weeks; closes 20.9 weeks out; review 4 weeks; speakers hear back 16.9 weeks out)\nFormats (structure / call / slots / form fields):\n  Talk (30 min) | in structure yes | in call yes | slots 18 | fields: Title; Abstract (100 words); Why me; Audience level; Bio; Prior talk links\n  Lightning talk (5 min) | in structure yes | in call yes | slots 6 | fields: Title; Abstract (100 words); Bio\n  Workshop (2 h) | in structure yes | in call no | slots 2 | fields: none\n  Panel | in structure no | in call yes | slots 1 | fields: Title; Panelists\nPer-person cap: 3\nAnonymization as planned: Named review\nCriteria as drafted:\n  1. No speaker spot can be bought by a sponsor - ever.\n  2. New content is favored over talks already given elsewhere.\n  3. We actively favor new speakers.\n  4. Product and tool talks go to the open space sessions.\nBenefits as drafted:\n  Free event ticket | confirmed\n  Travel reimbursement | NOT confirmed",
 "facts": "Timeline: the dates make a long (Long window); the page's pick is long (a first edition reading CFP volume as demand, international speakers with visa lead times)\nFormats the call offers: Talk (30 min) (18 slots), Lightning talk (5 min) (6 slots), Panel (1 slots)\nForm depth: the fields make standard; the page's pick is extended\nAnonymization: planned named; the page's pick is named\nCriteria against the six community-pole points: No sponsor-bought speaker spots - present; New content favored - present; Local and out-of-town balance - MISSING; New speakers favored - present; Bold subjects encouraged - MISSING; Product talks routed to open space (or a lesson-transfer test) - present\nBenefits the call may state (confirmed): Free event ticket\nFirst-time-speaker support: encouragement (a first edition has no archive - the criteria and a split form do the calibrating)\nGates (2 of 4): The timeline sits at or above the sourced floor passed; The call offers exactly the structure's formats MISSING; Review criteria are published in the call passed; Benefits state the free-ticket floor and nothing unconfirmed MISSING\nSignals to record: Submissions-to-slot ratio at close (self-set threshold); First-time-submitter share (self-set threshold); Where in the window submissions arrive - a dead middle blames the promotion (self-set)\nFindings (10):\n[info] sustain (promotion): A long window is a promotion commitment, not just an early open date: plan posts across the whole window, or it sits silent in the middle.\n[fix] format_extra (formats): The call offers formats the structure does not have: Panel - submissions nobody can schedule.\n[fix] format_missing (formats): The structure has formats the call leaves out: Workshop (2 h).\n[check] depth (form): The fields make a standard form; the page's pick is extended (formats with different requirements).\n[check] crit_missing (criteria): Not in the published criteria: local and out-of-town balance; bold subjects encouraged.\n[fix] no_open_space (criteria): The criteria route product talks to an open space the structure does not have - publish the lesson-transfer test instead.\n[check] lesson_test (criteria): No open-space block: publish the lesson-transfer test so a founder can self-check - would the audience keep the lesson if they forgot the product name tomorrow?\n[fix] unconfirmed (benefits): Unconfirmed, so not in the call: Travel reimbursement - the call states exactly what speakers get and nothing the budget has not confirmed.\n[check] outreach (promotion): Diversity is a goal but nobody will reach out - under-represented people in tech are much less likely to respond to an open call.\n[check] gate (readiness): Before the call goes public: 2 of 4 - missing: the call offers exactly the structure's formats; benefits state the free-ticket floor and nothing unconfirmed (self-set)."
}

Reply:

{
 "task": "brief",
 "summary": "Long window for this first CFP; the most important fix is matching the call's formats to the structure (add Workshop, drop Panel); settle first whether travel reimbursement is actually funded.",
 "timeline": {
  "pick": "long",
  "planned": "long",
  "open": "2027-01-15",
  "close": "2027-04-30",
  "notify": "2027-05-28",
  "note": "The long window gives international speakers time for visas and travel while a first edition reads CFP volume as demand."
 },
 "formats": [
  {
   "format": "Talk (30 min)",
   "structure": true,
   "call": true,
   "note": "Keep this format as currently offered."
  },
  {
   "format": "Lightning talk (5 min)",
   "structure": true,
   "call": true,
   "note": "Keep this format as currently offered."
  },
  {
   "format": "Workshop (2 h)",
   "structure": true,
   "call": false,
   "note": "Add this format to the call since the structure already includes it."
  },
  {
   "format": "Panel",
   "structure": false,
   "call": true,
   "note": "Drop this format from the call since the structure does not include it."
  }
 ],
 "form": {
  "pick": "extended",
  "planned": "standard",
  "cap": 3,
  "note": "The drafted fields read as a standard-depth form, but the page recommends extended depth since the formats carry different requirements."
 },
 "review": {
  "pick": "named",
  "planned": "named",
  "note": "With a 3-person committee reviewing by name, publishing full criteria is what keeps the review honest."
 },
 "criteria": {
  "missing": [
   "Local and out-of-town balance",
   "Bold subjects encouraged"
  ],
  "note": "Some community-pole points are missing from the draft, and it routes product talks to an open space the structure does not have."
 },
 "benefits": {
  "state": [
   "Free event ticket"
  ],
  "drop": [
   "Travel reimbursement"
  ],
  "note": "Travel reimbursement is not yet confirmed by the budget, so it must stay out of the call until it is."
 },
 "support": {
  "pick": "encouragement",
  "note": "With no past proposals to draw worked examples from, encouragement copy together with the published criteria and split form fields does the calibrating this first time."
 },
 "measurement": [
  {
   "metric": "Submissions-to-slot ratio at close",
   "revision": "If the ratio comes in high across the Talk and Lightning formats, that argues for adding review capacity rather than opening more slots next edition."
  },
  {
   "metric": "First-time-submitter share",
   "revision": "A low share here would prompt building a mentor pool so next edition can offer proposal mentorship instead of only encouragement."
  },
  {
   "metric": "Where in the window submissions arrive",
   "revision": "A dead middle would prompt scheduling promotion posts across the whole long window instead of only at the open and close dates."
  }
 ],
 "caveats": [
  "The call offers Panel, a format the structure does not include, so submissions for it cannot be scheduled.",
  "The structure includes Workshop (2 h), a format the call leaves out.",
  "The criteria route product talks to an open space the structure does not have; publish the lesson-transfer test instead.",
  "Travel reimbursement is not confirmed by the budget, so it should not appear in the call."
 ]
}

The page's check: kept - nothing to flag

Mirrowmere DevOps Conference (a first community call) - call

Dates make a long window (the page's pick: long window); 3 formats in the call; form pick extended; review pick named; 2 of 4 gates.

Input:

{
 "task": "call",
 "event": "Event: Mirrowmere DevOps Conference 2027; event date 2027-09-23; a community conference - the call fills the program; first CFP; a compounding annual asset\nAs of: 2026-11-02 (46.4 weeks before the event); program announcement 2027-06-30\nTeam: review committee 3; mentor pool no; international speakers yes; diversity a stated goal yes; outreach capacity no; past accepted proposals to publish no\nStructure: open-space block no; fast-moving field no; slots held outside the call 0\nLast edition: no data",
 "design": "Timeline as planned: opens 2027-01-15, closes 2027-04-30, notifies 2027-05-28, event 2027-09-23 (open 15 weeks; closes 20.9 weeks out; review 4 weeks; speakers hear back 16.9 weeks out)\nFormats (structure / call / slots / form fields):\n  Talk (30 min) | in structure yes | in call yes | slots 18 | fields: Title; Abstract (100 words); Why me; Audience level; Bio; Prior talk links\n  Lightning talk (5 min) | in structure yes | in call yes | slots 6 | fields: Title; Abstract (100 words); Bio\n  Workshop (2 h) | in structure yes | in call no | slots 2 | fields: none\n  Panel | in structure no | in call yes | slots 1 | fields: Title; Panelists\nPer-person cap: 3\nAnonymization as planned: Named review\nCriteria as drafted:\n  1. No speaker spot can be bought by a sponsor - ever.\n  2. New content is favored over talks already given elsewhere.\n  3. We actively favor new speakers.\n  4. Product and tool talks go to the open space sessions.\nBenefits as drafted:\n  Free event ticket | confirmed\n  Travel reimbursement | NOT confirmed",
 "facts": "Timeline: the dates make a long (Long window); the page's pick is long (a first edition reading CFP volume as demand, international speakers with visa lead times)\nFormats the call offers: Talk (30 min) (18 slots), Lightning talk (5 min) (6 slots), Panel (1 slots)\nForm depth: the fields make standard; the page's pick is extended\nAnonymization: planned named; the page's pick is named\nCriteria against the six community-pole points: No sponsor-bought speaker spots - present; New content favored - present; Local and out-of-town balance - MISSING; New speakers favored - present; Bold subjects encouraged - MISSING; Product talks routed to open space (or a lesson-transfer test) - present\nBenefits the call may state (confirmed): Free event ticket\nFirst-time-speaker support: encouragement (a first edition has no archive - the criteria and a split form do the calibrating)\nGates (2 of 4): The timeline sits at or above the sourced floor passed; The call offers exactly the structure's formats MISSING; Review criteria are published in the call passed; Benefits state the free-ticket floor and nothing unconfirmed MISSING\nSignals to record: Submissions-to-slot ratio at close (self-set threshold); First-time-submitter share (self-set threshold); Where in the window submissions arrive - a dead middle blames the promotion (self-set)\nFindings (10):\n[info] sustain (promotion): A long window is a promotion commitment, not just an early open date: plan posts across the whole window, or it sits silent in the middle.\n[fix] format_extra (formats): The call offers formats the structure does not have: Panel - submissions nobody can schedule.\n[fix] format_missing (formats): The structure has formats the call leaves out: Workshop (2 h).\n[check] depth (form): The fields make a standard form; the page's pick is extended (formats with different requirements).\n[check] crit_missing (criteria): Not in the published criteria: local and out-of-town balance; bold subjects encouraged.\n[fix] no_open_space (criteria): The criteria route product talks to an open space the structure does not have - publish the lesson-transfer test instead.\n[check] lesson_test (criteria): No open-space block: publish the lesson-transfer test so a founder can self-check - would the audience keep the lesson if they forgot the product name tomorrow?\n[fix] unconfirmed (benefits): Unconfirmed, so not in the call: Travel reimbursement - the call states exactly what speakers get and nothing the budget has not confirmed.\n[check] outreach (promotion): Diversity is a goal but nobody will reach out - under-represented people in tech are much less likely to respond to an open call.\n[check] gate (readiness): Before the call goes public: 2 of 4 - missing: the call offers exactly the structure's formats; benefits state the free-ticket floor and nothing unconfirmed (self-set)."
}

Reply:

{
 "task": "call",
 "title": "Call for papers - Mirrowmere DevOps Conference 2027",
 "intro": "Mirrowmere DevOps Conference 2027 is a new community conference for DevOps practitioners, and this is our first call for papers. We are looking for speakers from anywhere, including first-time speakers, with ideas on DevOps practice, tooling and culture. If you have a talk, lightning talk or workshop idea, we want to hear from you.",
 "dates": [
  {
   "label": "Call opens",
   "date": "2027-01-15"
  },
  {
   "label": "Call closes",
   "date": "2027-04-30"
  },
  {
   "label": "Speakers hear back",
   "date": "2027-05-28"
  },
  {
   "label": "Event",
   "date": "2027-09-23"
  }
 ],
 "formats": [
  {
   "format": "Talk (30 min)",
   "slots": 18,
   "submit": "Send a title, a roughly 100-word abstract, a short note on why you are the right person to give this talk, your audience level, a bio and links to any prior talks."
  },
  {
   "format": "Lightning talk (5 min)",
   "slots": 6,
   "submit": "Send a title, a roughly 100-word abstract and a bio."
  },
  {
   "format": "Workshop (2 h)",
   "slots": 2,
   "submit": "[fields to set]"
  }
 ],
 "cap": "Each person may submit up to 3 proposals across all formats.",
 "review": "Proposals are reviewed by name, not anonymized, by our 3-person review committee. We publish the criteria we use below so you know what we are weighing when we select talks.",
 "criteria": [
  "No speaker spot can be bought by a sponsor - ever.",
  "New content is favored over talks already given elsewhere.",
  "We actively favor new speakers.",
  "For product and tool talks: would the audience still keep the lesson if they forgot the product name tomorrow?"
 ],
 "benefits": [
  "Free event ticket"
 ],
 "firsttimers": "This is our first call for papers, so we have no past accepted talks to show you yet - but we actively favor new speakers, and the submission form lets you make the case for yourself alongside your idea. If you have never spoken at a conference before, we still want to hear from you.",
 "reserved": "",
 "contact": "[contact address]"
}

The page's check: kept - nothing to flag

Quillhaven JS Day (a repeat call on a short runway) - brief

Dates make a floor-compressed (the page's pick: floor-compressed); 1 formats in the call; form pick standard; review pick blind; 4 of 4 gates.

Input:

{
 "task": "brief",
 "event": "Event: Quillhaven JS Day 2027; event date 2027-03-18; a community conference - the call fills the program; repeat CFP; a compounding annual asset\nAs of: 2026-12-01 (15.3 weeks before the event); program announcement 2027-02-15\nTeam: review committee 5; mentor pool no; international speakers no; diversity a stated goal yes; outreach capacity yes; past accepted proposals to publish yes\nStructure: open-space block yes; fast-moving field yes; slots held outside the call 2 (count stated in the call: yes)\nLast edition: 34 submissions for 8 slots",
 "design": "Timeline as planned: opens 2026-12-07, closes 2027-01-28, notifies 2027-02-11, event 2027-03-18 (open 7.4 weeks; closes 7 weeks out; review 2 weeks; speakers hear back 5 weeks out)\nFormats (structure / call / slots / form fields):\n  Talk (25 min) | in structure yes | in call yes | slots 8 | fields: Title; Abstract (250 words); Bio\nPer-person cap: 2\nAnonymization as planned: Mandatory blind; identity enters: NOT STATED; speakers told to self-police identifying details: no\nCriteria as drafted:\n  1. No sponsor can buy a speaking slot.\n  2. Unpublished material is favored.\n  3. We balance local and out-of-town speakers.\n  4. First-time speakers are actively favored.\n  5. Bold subjects are welcome.\n  6. Vendor and product talks are routed to the open space.\nBenefits as drafted:\n  Free event ticket | confirmed\n  Honorarium of 200 dollars | confirmed",
 "facts": "Timeline: the dates make a floor (Floor-compressed); the page's pick is floor (under about 16 weeks of runway - only the compressed window fits)\nFormats the call offers: Talk (25 min) (8 slots)\nForm depth: the fields make minimal; the page's pick is standard\nAnonymization: planned blind; the page's pick is blind\nCriteria against the six community-pole points: No sponsor-bought speaker spots - present; New content favored - present; Local and out-of-town balance - present; New speakers favored - present; Bold subjects encouraged - present; Product talks routed to open space (or a lesson-transfer test) - present\nBenefits the call may state (confirmed): Free event ticket; Honorarium of 200 dollars\nFirst-time-speaker support: examples (past accepted proposals to publish as calibration)\nGates (4 of 4): The timeline sits at or above the sourced floor passed; The call offers exactly the structure's formats passed; Review criteria are published in the call passed; Benefits state the free-ticket floor and nothing unconfirmed passed\nSignals to record: Submissions-to-slot ratio at close (self-set threshold); First-time-submitter share (self-set threshold); Where in the window submissions arrive - a dead middle blames the promotion (self-set)\nFindings (9):\n[fix] late_notify (timeline): Speakers hear back 5 weeks before the event - inside the 4-6 weeks they need for travel.\n[check] depth (form): The fields make a minimal form; the page's pick is standard.\n[check] one_box (form): An abstract with no separate context (\"why me\") field - one text box cannot be scored on topic and speaker fit at once.\n[check] long_abstract (form): The abstract allows 250 words - cap it near 100; the title carries twice the abstract's weight.\n[fix] theater (review): Mandatory blind review with no stated point where identity enters - publish the two-phase mechanics, or it is blind-review theater.\n[check] self_police (review): Tell speakers to keep identifying details out of titles and free text - the platform hides the author field, not what the author wrote.\n[info] tax (benefits): Honorarium of 200 dollars: direct payment can bring tax, visa and conflict-of-interest or employment-agreement issues - check before publishing.\n[info] ratio (measurement): Last edition drew 34 submissions for 8 slots (4.3 to 1). Oversubscription is the normal state of a healthy call - the fix for volume is review capacity.\n[info] gate (readiness): Before the call goes public: 4 of 4 (self-set)."
}

Reply:

{
 "task": "brief",
 "summary": "Floor-compressed timeline for this repeat CFP; fix the 5-week notify-to-event gap so speakers have travel time; settle when identity enters the mandatory blind review first.",
 "timeline": {
  "pick": "floor",
  "planned": "floor",
  "open": "2026-12-07",
  "close": "2027-01-28",
  "notify": "2027-02-11",
  "note": "The compressed floor window is the only one that fits this runway, and notifying 5 weeks before the event leaves speakers less than the 4-6 weeks they need to arrange travel."
 },
 "formats": [
  {
   "format": "Talk (25 min)",
   "structure": true,
   "call": true,
   "note": "Keep this format as currently offered."
  }
 ],
 "form": {
  "pick": "standard",
  "planned": "minimal",
  "cap": 2,
  "note": "The drafted fields make this a minimal form; the page recommends standard depth with a separate context field."
 },
 "review": {
  "pick": "blind",
  "planned": "blind",
  "note": "Run the review in two stated phases, publish exactly when identity enters, and tell speakers to keep identifying details out of titles and free text."
 },
 "criteria": {
  "missing": [],
  "note": "All six community-pole points are already present in the draft, including routing vendor and product talks to the open space the structure has."
 },
 "benefits": {
  "state": [
   "Free event ticket",
   "Honorarium of 200 dollars"
  ],
  "drop": [],
  "note": "A direct cash honorarium can raise tax, visa and conflict-of-interest questions worth checking before this goes out."
 },
 "support": {
  "pick": "examples",
  "note": "Publishing past accepted proposals as worked examples does the calibration for this repeat CFP."
 },
 "measurement": [
  {
   "metric": "Submissions-to-slot ratio at close",
   "revision": "If the ratio comes in far above last edition's 34 submissions for 8 slots, that argues for adding review capacity rather than more slots next time."
  },
  {
   "metric": "First-time-submitter share",
   "revision": "A low first-time share despite having outreach capacity would prompt directing that capacity specifically at under-represented submitters next edition."
  }
 ],
 "caveats": [
  "Speakers hear back only 5 weeks before the event, inside the 4-6 weeks they need for travel.",
  "Mandatory blind review does not state when identity enters the process.",
  "The abstract field allows 250 words instead of near 100, and the title already carries twice the abstract's weight.",
  "The form has no separate context field, so one box cannot score topic and speaker fit at once."
 ]
}

The page's check: kept - nothing to flag

Quillhaven JS Day (a repeat call on a short runway) - call

Dates make a floor-compressed (the page's pick: floor-compressed); 1 formats in the call; form pick standard; review pick blind; 4 of 4 gates.

Input:

{
 "task": "call",
 "event": "Event: Quillhaven JS Day 2027; event date 2027-03-18; a community conference - the call fills the program; repeat CFP; a compounding annual asset\nAs of: 2026-12-01 (15.3 weeks before the event); program announcement 2027-02-15\nTeam: review committee 5; mentor pool no; international speakers no; diversity a stated goal yes; outreach capacity yes; past accepted proposals to publish yes\nStructure: open-space block yes; fast-moving field yes; slots held outside the call 2 (count stated in the call: yes)\nLast edition: 34 submissions for 8 slots",
 "design": "Timeline as planned: opens 2026-12-07, closes 2027-01-28, notifies 2027-02-11, event 2027-03-18 (open 7.4 weeks; closes 7 weeks out; review 2 weeks; speakers hear back 5 weeks out)\nFormats (structure / call / slots / form fields):\n  Talk (25 min) | in structure yes | in call yes | slots 8 | fields: Title; Abstract (250 words); Bio\nPer-person cap: 2\nAnonymization as planned: Mandatory blind; identity enters: NOT STATED; speakers told to self-police identifying details: no\nCriteria as drafted:\n  1. No sponsor can buy a speaking slot.\n  2. Unpublished material is favored.\n  3. We balance local and out-of-town speakers.\n  4. First-time speakers are actively favored.\n  5. Bold subjects are welcome.\n  6. Vendor and product talks are routed to the open space.\nBenefits as drafted:\n  Free event ticket | confirmed\n  Honorarium of 200 dollars | confirmed",
 "facts": "Timeline: the dates make a floor (Floor-compressed); the page's pick is floor (under about 16 weeks of runway - only the compressed window fits)\nFormats the call offers: Talk (25 min) (8 slots)\nForm depth: the fields make minimal; the page's pick is standard\nAnonymization: planned blind; the page's pick is blind\nCriteria against the six community-pole points: No sponsor-bought speaker spots - present; New content favored - present; Local and out-of-town balance - present; New speakers favored - present; Bold subjects encouraged - present; Product talks routed to open space (or a lesson-transfer test) - present\nBenefits the call may state (confirmed): Free event ticket; Honorarium of 200 dollars\nFirst-time-speaker support: examples (past accepted proposals to publish as calibration)\nGates (4 of 4): The timeline sits at or above the sourced floor passed; The call offers exactly the structure's formats passed; Review criteria are published in the call passed; Benefits state the free-ticket floor and nothing unconfirmed passed\nSignals to record: Submissions-to-slot ratio at close (self-set threshold); First-time-submitter share (self-set threshold); Where in the window submissions arrive - a dead middle blames the promotion (self-set)\nFindings (9):\n[fix] late_notify (timeline): Speakers hear back 5 weeks before the event - inside the 4-6 weeks they need for travel.\n[check] depth (form): The fields make a minimal form; the page's pick is standard.\n[check] one_box (form): An abstract with no separate context (\"why me\") field - one text box cannot be scored on topic and speaker fit at once.\n[check] long_abstract (form): The abstract allows 250 words - cap it near 100; the title carries twice the abstract's weight.\n[fix] theater (review): Mandatory blind review with no stated point where identity enters - publish the two-phase mechanics, or it is blind-review theater.\n[check] self_police (review): Tell speakers to keep identifying details out of titles and free text - the platform hides the author field, not what the author wrote.\n[info] tax (benefits): Honorarium of 200 dollars: direct payment can bring tax, visa and conflict-of-interest or employment-agreement issues - check before publishing.\n[info] ratio (measurement): Last edition drew 34 submissions for 8 slots (4.3 to 1). Oversubscription is the normal state of a healthy call - the fix for volume is review capacity.\n[info] gate (readiness): Before the call goes public: 4 of 4 (self-set)."
}

Reply:

{
 "task": "call",
 "title": "Call for papers - Quillhaven JS Day 2027",
 "intro": "Quillhaven JS Day 2027 is our community conference for the fast-moving JavaScript ecosystem, and we are opening our call for papers again this year. We want to hear from local and out-of-town developers with new, unpublished ideas, and we especially encourage first-time and under-represented speakers to submit. There is also an open space track for vendor and product talks that do not fit the main program.",
 "dates": [
  {
   "label": "Call opens",
   "date": "2026-12-07"
  },
  {
   "label": "Call closes",
   "date": "2027-01-28"
  },
  {
   "label": "Speakers hear back",
   "date": "2027-02-11"
  },
  {
   "label": "Event",
   "date": "2027-03-18"
  }
 ],
 "formats": [
  {
   "format": "Talk (25 min)",
   "slots": 8,
   "submit": "Send a title, a 250-word abstract and a bio."
  }
 ],
 "cap": "Each person may submit up to 2 proposals.",
 "review": "Proposals are reviewed blind, in two phases: our 5-person committee first scores each proposal with the speaker's identity hidden, and [when identity enters]. Please keep your name, employer and other identifying details out of your title and the body of your proposal.",
 "criteria": [
  "No sponsor can buy a speaking slot.",
  "Unpublished material is favored.",
  "We balance local and out-of-town speakers.",
  "First-time speakers are actively favored.",
  "Bold subjects are welcome.",
  "Vendor and product talks are routed to the open space."
 ],
 "benefits": [
  "Free event ticket",
  "Honorarium of 200 dollars"
 ],
 "firsttimers": "If you have not spoken before, we publish examples of past accepted proposals so you can see what a successful submission looks like. First-time speakers are actively favored in our review.",
 "reserved": "2 additional slots are held outside this call for invited speakers.",
 "contact": "[contact address]"
}

The page's check: kept - nothing to flag

Brindlewick User Summit (a vendor call, eight weeks out) - brief

Dates make a below the floor - open call deleted (the page's pick: below the floor - open call deleted); 1 formats in the call; form pick minimal; review pick named; 1 of 4 gates.

Input:

{
 "task": "brief",
 "event": "Event: Brindlewick User Summit; event date 2027-02-10; a vendor or user conference - the call fills a community slice; first CFP; a one-off\nAs of: 2026-12-10 (8.9 weeks before the event); program announcement 2027-01-20\nTeam: review committee 2; mentor pool no; international speakers no; diversity a stated goal no; outreach capacity no; past accepted proposals to publish no\nStructure: open-space block no; fast-moving field no; slots held outside the call 0\nLast edition: no data",
 "design": "Timeline as planned: opens 2026-12-15, closes 2027-01-05, notifies 2027-01-12, event 2027-02-10 (open 3 weeks; closes 5.1 weeks out; review 1 weeks; speakers hear back 4.1 weeks out)\nFormats (structure / call / slots / form fields):\n  Customer story (20 min) | in structure yes | in call yes | slots 4 | fields: Title; Abstract; Company\nPer-person cap: not set\nAnonymization as planned: Opt-in anonymous\nCriteria as drafted: none\nBenefits as drafted:\n  Free event ticket | confirmed\n  Hotel for two nights | NOT confirmed",
 "facts": "Timeline: the dates make a below (Below the floor - open call deleted); the page's pick is below (the event is closer than about 10 weeks)\nFormats the call offers: Customer story (20 min) (4 slots)\nForm depth: the fields make minimal; the page's pick is minimal\nAnonymization: planned optin; the page's pick is named\nCriteria against the six community-pole points: No sponsor-bought speaker spots - MISSING; New content favored - MISSING; Local and out-of-town balance - MISSING; New speakers favored - MISSING; Bold subjects encouraged - MISSING; Product talks routed to open space (or a lesson-transfer test) - MISSING\nBenefits the call may state (confirmed): Free event ticket\nFirst-time-speaker support: encouragement (a first edition has no archive - the criteria and a split form do the calibrating)\nGates (1 of 4): The timeline sits at or above the sourced floor MISSING; The call offers exactly the structure's formats passed; Review criteria are published in the call MISSING; Benefits state the free-ticket floor and nothing unconfirmed MISSING\nSignals to record: Submissions-to-slot ratio at close (self-set threshold); First-time-submitter share (self-set threshold); Where in the window submissions arrive - a dead middle blames the promotion (self-set)\nFindings (13):\n[fix] short_open (timeline): Open for 3 weeks - keep the call open for at least a month.\n[fix] late_close (timeline): Closes 5.1 weeks before the event - close at least 6-8 weeks out; people need at least 4-6 weeks to arrange travel or time off.\n[fix] short_review (timeline): Only 1 week between close and notification - leave at least 2 weeks to consider proposals and fill gaps.\n[fix] deleted (timeline): The event is 8.9 weeks away - below the floor the open CFP is deleted, not compressed: go invited through speaker sourcing.\n[check] one_box (form): An abstract with no separate context (\"why me\") field - one text box cannot be scored on topic and speaker fit at once.\n[check] no_cap (form): No per-person submission cap - set one (the sourced example is three proposals per person).\n[info] vendor (formats): A vendor or user conference: the call fills a community slice of a curated program, and its timeline couples to the vendor's launch calendar.\n[check] optin (review): Opt-in anonymity is a platform capability, not a fairness posture - a pool mixing named and anonymous submissions is not reviewed on one footing.\n[info] anon_pick (review): The page's pick is named review (named, with published criteria doing the fairness work).\n[fix] no_criteria (criteria): No review criteria in the call - unstated criteria make rejections read as arbitrary.\n[fix] unconfirmed (benefits): Unconfirmed, so not in the call: Hotel for two nights - the call states exactly what speakers get and nothing the budget has not confirmed.\n[info] equity (promotion): Under-represented people in tech are much less likely to respond to an open call; the call alone will not reach them.\n[check] gate (readiness): Before the call goes public: 1 of 4 - missing: the timeline sits at or above the sourced floor; review criteria are published in the call; benefits state the free-ticket floor and nothing unconfirmed (self-set)."
}

Reply:

{
 "task": "brief",
 "summary": "Below the floor for this first CFP; the most important fix is deleting the open call and sourcing speakers by invitation instead; settle whether Hotel for two nights is funded before publishing anything else.",
 "timeline": {
  "pick": "below",
  "planned": "below",
  "open": "2026-12-15",
  "close": "2027-01-05",
  "notify": "2027-01-12",
  "note": "At 8.9 weeks out this sits below the floor, so the open call should be deleted and the program filled through invited speaker sourcing instead."
 },
 "formats": [
  {
   "format": "Customer story (20 min)",
   "structure": true,
   "call": true,
   "note": "Keep this format as currently offered."
  }
 ],
 "form": {
  "pick": "minimal",
  "planned": "minimal",
  "cap": null,
  "note": "No per-person cap is set yet; the sourced example suggests three proposals per person."
 },
 "review": {
  "pick": "named",
  "planned": "optin",
  "note": "Opt-in anonymity is a platform toggle, not a fairness posture, so the page recommends named review backed by published criteria instead."
 },
 "criteria": {
  "missing": [
   "No sponsor-bought speaker spots",
   "New content favored",
   "Local and out-of-town balance",
   "New speakers favored",
   "Bold subjects encouraged",
   "Product talks routed to open space (or a lesson-transfer test)"
  ],
  "note": "None of the six community-pole points are drafted yet, so unstated criteria would make any rejection look arbitrary."
 },
 "benefits": {
  "state": [
   "Free event ticket"
  ],
  "drop": [
   "Hotel for two nights"
  ],
  "note": "Hotel for two nights is not yet confirmed by the budget, so it must stay out of the call until it is."
 },
 "support": {
  "pick": "encouragement",
  "note": "With no past proposals and no mentor pool, encouragement copy together with published criteria would do the calibrating once criteria exist."
 },
 "measurement": [
  {
   "metric": "Submissions-to-slot ratio at close",
   "revision": "A low ratio against the 4 slots offered would suggest promotion needs work if an open call is tried again."
  },
  {
   "metric": "First-time-submitter share",
   "revision": "A low first-time share would flag that active outreach is needed even though diversity is not currently a stated goal."
  }
 ],
 "caveats": [
  "The call is open for only 3 weeks; keep it open at least a month.",
  "The call closes 5.1 weeks before the event; close at least 6-8 weeks out so people have 4-6 weeks to arrange travel or time off.",
  "Only 1 week sits between close and notification; leave at least 2 weeks to consider proposals and fill gaps.",
  "The event is 8.9 weeks away, below the floor; delete the open call and go invited through speaker sourcing instead."
 ]
}

The page's check: kept - nothing to flag

The form-fields CSV for the first sample

format,in_structure,in_call,slots,field
Talk (30 min),yes,yes,18,Title
Talk (30 min),yes,yes,18,Abstract (100 words)
Talk (30 min),yes,yes,18,Why me
Talk (30 min),yes,yes,18,Audience level
Talk (30 min),yes,yes,18,Bio
Talk (30 min),yes,yes,18,Prior talk links
Lightning talk (5 min),yes,yes,6,Title
Lightning talk (5 min),yes,yes,6,Abstract (100 words)
Lightning talk (5 min),yes,yes,6,Bio
Workshop (2 h),yes,no,2,
Panel,no,yes,1,Title
Panel,no,yes,1,Panelists

Build the input yourself

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

const K = CfpKit, R = CfpReply;
const f = K.form({ name: "My Conf", event: "2027-09-23", open: "2027-04-01", close: "2027-06-01", notify: "2027-06-20", pole: "community",
  formats: fs.readFileSync("formats.csv", "utf8"), criteria: fs.readFileSync("criteria.txt", "utf8"), benefits: "benefit,confirmed\nFree event ticket,yes" });
// f.rung, f.rec, f.openWeeks, f.closeOut, f.review, f.offered, f.depth, f.recDepth, f.anon, f.recAnon, f.critHits
// f.published (confirmed benefits), f.support, f.gate, f.findings
K.formCSV(f)                                   // format, in_structure, in_call, slots, field
const b = K.buildInput(f, "brief");            // or "call"
const wire = K.toWire(b.input);                // POST this to /estimate and /run
// then: const reply = R.normalize(R.parseReply(job.output.output), "brief");
// R.check(reply, b)                           // {status: kept or flagged, notes}

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="paste-your-token-here"   # from https://cfp-blueprint.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":"cfp-blueprint"}' | 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": "brief", "event": "Event: ...; event date 2027-09-23; a community conference ...", "design": "Timeline as planned: opens 2027-01-15, closes ...", "facts": "Timeline: the dates make a long ..."}
# - 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 cfp-blueprint:<task>:<inputHash>:a<attempt> - the lane is part of the key - and its one automatic reformat retry is a new attempt number, named in the page as one extra run. A brief carries summary, timeline, formats, form, review, criteria, benefits, support, measurement and caveats; a call carries title, intro, dates, formats, cap, review, criteria, benefits, firsttimers, reserved and contact. The code below prints the headline parts of either (list items are plain strings).

KEY="cfp-blueprint:brief:$(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 '.summary // .format, .note // .intro, ((.signals // .caveats)[] | "\(.signal // .caveat): \(.text // .text)")' reply.json
jq -r '.review // .note // empty' reply.json   # how proposals are reviewed (call)

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: cfp-blueprint:brief:$(shasum -a 256 input.json | cut -c1-16):a1" --data @input.json