← Magnet Desk / API
Tokens

Drive Magnet Desk from your own code

The page does its free work in the browser: it reads a pasted lead magnet and its context, names the format, buyer stage and length, finds the six areas the lead-magnets skill checks (the problem, the format, the capture, the landing page, the delivery, the distribution) with the line that shows each, computes landing-page conversion, lead-to-trial, lead-to-customer and cost per lead against the skill's benchmark for the format, and raises flags LM-01..LM-24. Its two paid lanes are available over HTTP. You send one JSON object with task set to "audit" or "plan", and the model replies with one JSON object. The easiest way to build the facts string is the page itself: Magkit.buildInput(lane, Magkit.analyze(magnet, {context, goal, stage, question}), {auditHandoff}) in magnetkit.js, which also runs under Node.

Base URL: https://api.skillsafe.ai/v1/app-api. Every call sends Content-Type: application/json and, once you have a token, Authorization: Bearer <token>. Both lanes run on gpt-terra with a 10% publisher markup. A run needs a signed-in (user) token and is metered: the platform holds the estimate's hold_credits while the run is in flight and then charges only what it used (charged_credits). /estimate is free. A plain-text summary is at /llms.txt.

The response envelope

Every response is {"data": ..., "error": null} on success or {"data": null, "error": {"code", "message"}} on failure.

Error codes

HTTPcodemeaning
400VALIDATION_ERRORThe body is not a JSON object, or a field is the wrong type. Every field of the run input is a string.
401UNAUTHORIZEDNo token, or an expired one: get a new one (step 2).
402INSUFFICIENT_CREDITSThe balance is below the run's minimum. Top up at skillsafe.ai/account/billing/.
403FORBIDDENA guest token tried a metered run: sign in for a personal token.
404NOT_FOUNDUnknown job id.
429RATE_LIMITEDBack off and retry with the same Idempotency-Key.

The task field: two lanes

taskwhat the model does
"audit"The lead magnet audit: the magnet (title, format, buyer stage, a one-line read); the six areas (problem, format, capture, page, delivery, distribution) each good, weak, bad or unknown with a finding, quotes and a fix; the numbers (the page's conversion rate, the format's benchmark, below, within, above or unknown, and lead-to-customer); the issues as finding, impact and fix with the page's flag ids; 3 to 6 fixes; a verdict keep, fix_first or remake.
"plan"The lead magnet to build: a recommendation (title, one format, one specific topic, buyer stage, why, path to the product, the skill's effort and time to create); an outline (3 to 10 sections, length, minutes to consume, what makes it unique); the capture plan (gate, at most two fields, the six-part landing page, button, reassurance, delivery, thank-you page); 3 to 6 distribution channels; 2 to 5 follow_up steps; 3 to 6 metrics with targets; 2 to 4 tests.

Input fields (all strings)

fieldwhencontent
taskrequiredaudit or plan
magnetrequiredThe lead magnet as pasted, or what the business has to work with when it does not exist yet. Past 6,000 characters the page cuts the middle on line boundaries and leaves a [magnet-desk: ...] marker.
factsrequiredA JSON string: magnet (title, planned, format, stage, pages, minutes, items, mixed), goal, areas (problem, format, capture, page, delivery, distribution: found, evidence, note), found, capture, page, delivery, channels, blog_traffic, counts, metrics, benchmark, bench_verdict, effort, create_time, flags, notes. It is Magkit.factsOf(A).
contextoptionalThe business, the ideal customer, the product and the numbers. Cut past 4,000 characters.
goaloptionallist_growth, lead_quality or product_education.
stageoptionalThe buyer stage when the user chose it: awareness, consideration or decision.
questionoptionalWhat the user wants to know.
audit_handoffplan onlyA JSON string of an audit's verdict, bad[] (areas), issues[{flag, finding, fix}] and fixes[], for the same input.
retry_noteoptionalOnly on a reformat retry: what was wrong with the previous reply.

The reply contracts

Both lanes share an envelope: task, headline, questions[], summary.

task: "audit"

magnet{title, format, stage, read}, areas[{area: problem|format|capture|page|delivery|distribution, status: good|weak|bad|unknown, finding, evidence[], fix}] (exactly six, in order), numbers{conversion_rate, benchmark, verdict: below|within|above|unknown, lead_to_customer, read}, issues[{flag, kind: problem|format|capture|page|delivery|distribution|performance|quality|measurement, severity: high|medium|low, finding, impact, evidence[], fix}], fixes[] (3 to 6), verdict (keep|fix_first|remake).

task: "plan"

source (audit handoff|from the input), recommendation{title, format, topic, stage, why, path_to_product, effort, time_to_create}, outline{sections[{title, detail}], length, consume_minutes, unique}, capture{gate: full|partial|ungated|content_upgrade, fields[], why, page[{part: headline|preview|inside|proof|form|faq, copy}], cta, reassurance, delivery: instant|email|thankyou_email|drip, thank_you[]}, distribution[{channel: blog_cta|content_upgrade|popup|social|paid|partner|email|seo|sidebar, action}], follow_up[], measurement[{metric, target}], tests[{test, hypothesis, metric}].

Worked examples

These are the page's own bundled examples (invented businesses and numbers), with the input as app.js builds it and the saved model reply the page replays for free.

Audit: a bookkeeping SaaS's 48-page ebook behind six fields, converting at 4%

Input (magnet and facts shortened here):

{
 "task": "audit",
 "magnet": "Lead magnet: \"The Complete Guide to Small Business Finance\"\nFormat: a 48-page PDF ebook, plus a cash-flow spreadsheet and a 20-minute video walkthrough in the same download.\nIt covers bookkeeping basics, taxes, payroll, pricing, fundraising and hiring an accountant.\n\nLanding page\nHeadline: \"Download our free ebook\"\nBelow it a paragraph about why finance matters for founders. No preview of the ebook and no testimonial... (813 characters in all)",
 "facts": "(a JSON string; decoded: ebook, stage awareness, 6 of 6 areas stated, 6 form field(s), conversion 4% against 20-35% (below), lead-to-customer 0.54%, flags LM-03, LM-06, LM-20, LM-01, LM-04, LM-07, LM-10, LM-15, LM-16, LM-18, LM-21, LM-09, LM-11, LM-12, LM-13, LM-14, LM-17, LM-19)",
 "context": "Tallymoth - bookkeeping software for freelancers and small agencies (B2B SaaS, $29 a month after a 14-day free trial).\nMost of our traffic comes from the blog: posts on invoicing, quarterly taxes and expenses.\nLast quarter the ebook landing page had 9,200 visitors and 368 downloads.\nOf those leads, 2 became paying customers.\n",
 "goal": "lead_quality",
 "question": "We spent three months on this ebook and the landing page converts at 4%. Should we keep iterating on it?"
}

Reply:

{
 "task": "audit",
 "magnet": {
  "title": "The Complete Guide to Small Business Finance",
  "format": "ebook",
  "stage": "awareness",
  "read": "A 48-page finance ebook bundled with a spreadsheet and a video, aimed at small business founders in general rather than the freelancers and small agencies Tallymoth sells to."
 },
 "areas": [
  {
   "area": "problem",
   "status": "bad",
   "finding": "It promises a whole subject, from taxes to fundraising, instead of one problem that Tallymoth's bookkeeping software solves.",
   "evidence": [
    "Lead magnet: \"The Complete Guide to Small Business Finance\"",
    "It covers bookkeeping basics, taxes, payroll, pricing, fundraising and hiring an accountant."
   ],
   "fix": "Pick one pain your blog readers already have, such as setting money aside for quarterly taxes, and solve only that."
  },
  {
   "area": "format",
   "status": "bad",
   "finding": "At 48 pages plus a spreadsheet and a video it is far past the skill's 10-25 page ebook and cannot be consumed in under 30 minutes.",
   "evidence": [
    "Format: a 48-page PDF ebook, plus a cash-flow spreadsheet and a 20-minute video walkthrough in the same download."
   ],
   "fix": "Ship one format that can be used in under 10 minutes; the cash-flow spreadsheet is the strongest candidate on its own."
  },
  {
   "area": "capture",
   "status": "bad",
   "finding": "The form asks for six fields including a phone number, with nothing by the form to reduce the risk.",
   "evidence": [
    "Form fields: first name, last name, work email, phone number, company size and job title."
   ],
   "fix": "Ask for email and first name only, and add \"No spam. Unsubscribe anytime.\" with a privacy link under the button."
  },
  {
   "area": "page",
   "status": "bad",
   "finding": "The 
... (shortened here; the page shows it whole)

Plan: the same business, carrying the audit

Input (with the audit handed over):

{
 "task": "plan",
 "magnet": "Lead magnet: \"The Complete Guide to Small Business Finance\"\nFormat: a 48-page PDF ebook, plus a cash-flow spreadsheet and a 20-minute video walkthrough in the same download.\nIt covers bookkeeping basics, taxes, payroll, pricing, fundraising and hiring an accountant.\n\nLanding page\nHeadline: \"Download our free ebook\"\nBelow it a paragraph about why finance matters for founders. No preview of the ebook and no testimonial... (813 characters in all)",
 "facts": "(a JSON string; decoded: ebook, stage awareness, 6 of 6 areas stated, 6 form field(s), conversion 4% against 20-35% (below), lead-to-customer 0.54%, flags LM-03, LM-06, LM-20, LM-01, LM-04, LM-07, LM-10, LM-15, LM-16, LM-18, LM-21, LM-09, LM-11, LM-12, LM-13, LM-14, LM-17, LM-19)",
 "context": "Tallymoth - bookkeeping software for freelancers and small agencies (B2B SaaS, $29 a month after a 14-day free trial).\nMost of our traffic comes from the blog: posts on invoicing, quarterly taxes and expenses.\nLast quarter the ebook landing page had 9,200 visitors and 368 downloads.\nOf those leads, 2 became paying customers.\n",
 "goal": "lead_quality",
 "question": "We spent three months on this ebook and the landing page converts at 4%. Should we keep iterating on it?",
 "audit_handoff": "{\"verdict\":\"remake\",\"bad\":[\"problem\",\"format\",\"capture\",\"page\",\"delivery\",\"distribution\"],\"issues\":[{\"flag\":\"LM-20\",\"finding\":\"The landing page converts at 4%, under the skill's 20-35% for an ebook.\",\"fix\":\"Fix the form and the page first, then measure the rebuilt magnet against its own format's benchmark.\"},{\"flag\":\"L..."
}

Reply:

{
 "task": "plan",
 "source": "audit handoff",
 "recommendation": {
  "title": "The Freelancer's Quarterly Tax Set-Aside Template",
  "format": "template",
  "topic": "Knowing how much of each invoice to set aside so the next quarterly tax payment is never a surprise.",
  "stage": "decision",
  "why": "For a lead quality goal, a template that freelancers fill in with their own invoices and expenses draws people already doing the work Tallymoth does, and it replaces the 48-page guide with something usable within 5 minutes.",
  "path_to_product": "The template makes them log every invoice and expense by hand, which is exactly the bookkeeping Tallymoth keeps for them, so the 14-day free trial is the natural next step.",
  "effort": "Low-Med",
  "time_to_create": "2-8 hours"
 },
 "outline": {
  "sections": [
   {
    "title": "Start here",
    "detail": "A short note on how to fill in the sheet and where to enter your own set-aside percentage, written as [your rate] rather than a figure we choose for them."
   },
   {
    "title": "Income log",
    "detail": "One row per paid invoice: client, date paid and amount, so income for the quarter totals itself."
   },
   {
    "title": "Expense log",
    "detail": "One row per business expense with a category, so deductible costs come off the total before the set-aside is worked out."
   },
   {
    "title": "Set-aside summary",
    "detail": "The amount to move into a tax account this quarter, worked out from the two logs and the rate they entered."
   },
   {
    "title": "Quarterly checklist",
    "detail": "The few things to check before each payment, with space for their own due dates."
   },
   {
    "title": "Do this automatically",
    "detail": "A closing note showing the same income and expense view inside Tallymoth, wit
... (shortened here; the page shows it whole)

Audit: an email platform's checklist content upgrade that mostly works

Input:

{
 "task": "audit",
 "magnet": "Title: The 12-Point Pre-Launch Email Checklist\nFormat: a 2-page printable checklist. It takes about 8 minutes to work through.\nIt is a content upgrade on our post \"How to launch a newsletter without landing in spam\": readers who finish the post get the checklist as a bonus.\n\nLanding page (an inline box at the end of the post)\nHeadline: \"Send your first newsletter without landing in spam\"\nA mockup of the checklist's f... (1099 characters in all)",
 "facts": "(a JSON string; decoded: checklist, stage awareness, 6 of 6 areas stated, 1 form field(s), conversion 6% against 3-8% (within), lead-to-customer 4.41%, flags none)",
 "context": "Inkwhistle - an email platform for first-time newsletter writers (B2B SaaS, free trial then paid plans).\nLast 90 days: the post had 3,400 readers and the checklist got 204 downloads.\nOf the 204 leads, 37 started a free trial and 9 became paying customers.\nWelcome series open rate 46%, click rate 4%.\n"
}

Reply:

{
 "task": "audit",
 "magnet": {
  "title": "The 12-Point Pre-Launch Email Checklist",
  "format": "checklist",
  "stage": "awareness",
  "read": "A 2-page checklist offered as a content upgrade to readers of a post on avoiding spam, for first-time newsletter writers about to send their first issue."
 },
 "areas": [
  {
   "area": "problem",
   "status": "good",
   "finding": "It solves one specific problem, landing in spam on a first send, which is exactly what Inkwhistle helps a new sender avoid.",
   "evidence": [
    "Headline: \"Send your first newsletter without landing in spam\"",
    "Inkwhistle - an email platform for first-time newsletter writers"
   ],
   "fix": ""
  },
  {
   "area": "format",
   "status": "good",
   "finding": "One printable format, 2 pages, and about 8 minutes to work through, inside the skill's ideal of under 10.",
   "evidence": [
    "Format: a 2-page printable checklist. It takes about 8 minutes to work through."
   ],
   "fix": ""
  },
  {
   "area": "capture",
   "status": "good",
   "finding": "A post-specific content upgrade behind an email-only form, with a no-spam line and a privacy link under the button.",
   "evidence": [
    "Form: email only.",
    "Under the button: \"No spam. Unsubscribe anytime.\" with a link to our privacy policy."
   ],
   "fix": ""
  },
  {
   "area": "page",
   "status": "good",
   "finding": "Five of the six parts are there in the right order: a benefit headline, a mockup, what's inside, a reader testimonial and a specific button; only an FAQ is missing.",
   "evidence": [
    "A mockup of the checklist's first page, and three bullets on what's inside",
    "Testimonial from a reader: \"I fixed my DKIM in ten minutes with this.\"",
    "Button: \"Send me the checklist\""
   ],
   "fix": ""
  },
  {
  
... (shortened here; the page shows it whole)

Plan: a puppy training app's first lead magnet, from a rough idea

Input:

{
 "task": "plan",
 "magnet": "We have no lead magnet yet. What we have to work with:\n- About 60 blog posts on puppy training; the most read is \"Crate training in the first week\"\n- Our trainers answer the same questions every day: crate training, biting, potty training, leash pulling\n- We post short training clips on Instagram and TikTok\n- Our app has a 7-day free trial and a paid plan; people who finish the first week of crate training in the app... (533 characters in all)",
 "facts": "(a JSON string; decoded: unclear, stage unclear, 1 of 6 areas stated, 0 form field(s), conversion unknown against no benchmark (unknown), lead-to-customer unknown, flags LM-19, LM-23)",
 "context": "Wagglestep - a puppy training app with video lessons and a daily plan (B2C subscription, $12.99 a month).\nMost new users find us through the blog and Instagram, mostly on phones.\nNew puppy owners are overwhelmed in the first two weeks and search for help at night.\n",
 "goal": "list_growth",
 "question": "What should we give away first?"
}

Reply:

{
 "task": "plan",
 "source": "from the input",
 "recommendation": {
  "title": "The First-Week Crate Training Checklist: Calm Nights With Your New Puppy",
  "format": "checklist",
  "topic": "Getting a new puppy to settle in the crate during the first week, including the nights.",
  "stage": "awareness",
  "why": "Overwhelmed new owners searching on their phones at night need a quick, printable or on-screen answer, and a checklist is the fastest awareness format to make and to use.",
  "path_to_product": "The checklist covers the first week of crate training, and people who finish that week in the app tend to stay, so the next step is the 7-day free trial with the same plan as daily video lessons.",
  "effort": "Low",
  "time_to_create": "1-2 hours"
 },
 "outline": {
  "sections": [
   {
    "title": "Before the puppy comes home",
    "detail": "Where to put the crate, what goes inside it and what to leave out."
   },
   {
    "title": "The first night",
    "detail": "The bedtime routine, the last potty trip and what to do when the whining starts."
   },
   {
    "title": "Daytime crate practice",
    "detail": "Short, positive crate sessions with treats and meals, and how to build them up through the week."
   },
   {
    "title": "When it goes wrong",
    "detail": "Crying, accidents in the crate and refusing to go in, each with one thing to try first."
   },
   {
    "title": "End of the week check",
    "detail": "The signs your puppy is settling, and the next skill to start with the Wagglestep daily plan."
   }
  ],
  "length": "A one-page checklist grouped into five short sections, readable on a phone.",
  "consume_minutes": 10,
  "unique": "It is the answer your trainers already give every day, turned into one week of clear steps an exhausted owner can follow a
... (shortened here; the page shows it whole)

The page re-checks the reply; the API does not

The page holds every reply to account (recon.js): for an audit, the magnet as the page read it and the stage you chose; six areas in order, none called good under a high or medium flag and every high flag's area called bad, nothing claimed for an area the paste never states without a quote; the conversion rate, benchmark, verdict and lead-to-customer rate equal to the page's arithmetic; every high and medium flag carried and a high one never downgraded; remake when two high flags stand or three areas are bad, and no "keep" while a high flag stands. For a plan, one real format and the stage you chose, the skill's effort and time to create, a specific topic, 3-10 sections, consumable in 30 minutes (60 for a webinar), an ebook within 25 pages, email and at most one more field and never a phone number, the six landing-page parts in order with a benefit headline and a specific button, a thank-you page with a next step, three or more channels, a follow-up, landing-page conversion and lead-to-customer measured against the skill's targets, tests with metrics, and the handed-off audit answered. In both, quotes are checked word for word and no count, rate, price or window may be invented beyond the skill's constants. Over the API you get the model's reply as it is; run the same checks yourself with Recon.reconcile in recon.js, or paste the same input into the page.

Step 1 — a tiny client helper

One function that sends JSON and unwraps the envelope.

BASE="https://api.skillsafe.ai/v1/app-api"
TOKEN="paste-your-token-here"   # from https://magnet-desk.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":"magnet-desk"}' | 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 (not wrapped in {"input": ...}). hold_credits is a reservation, not the price; min_credits is what the balance must cover; model reads gpt-5.6-terra and model_alias gpt-terra.

# input.json: the run input object - {"task": "audit", "magnet": "...", "context": "...", "facts": "..."}
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 magnet-desk:<lane>:<inputHash>:a<attempt>. The job's output.output is the reply text; truncated: true means the balance cut it short.

KEY="magnet-desk:audit:$(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 lane's contract
echo "$J" | jq '.data | {charged_credits, truncated}' 

Step 6 — POST /run-stream (plan)

The same run as Server-Sent Events. plan.json is a plan input, with audit_handoff when it follows an audit.

# 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: magnet-desk:plan:$(shasum -a 256 plan.json | cut -c1-16):a1" --data @plan.json