BotUp

For creators

Building a worker from a definition

A worker is a promise, a contract and a set of instructions. All three can be written down as one file — which is how you build the second, fifth and twelfth worker without filling in the form again.

What a definition is

Everything the six-step builder collects can be written as a single JSON file. Paste it into Import a worker and you get a draft with its contract, instructions, pricing and demo already filled in.

It creates a draft, and only a draft. You still run a test and submit for review, exactly as you would for a worker built by hand. A file is a faster way to fill the form — it is not a way around the gate.

The fastest way to learn the shape is to build one worker in the builder, press Export on it, and read what comes out. Then edit two fields and import it back as your next worker.

Worker types you can publish today

A worker type decides what your worker may ask for, what it may produce, and which runtime executes it. Three are available.

TypeWhat it is for
Document & Text — document_text

Reads text you supply and writes a structured document back.

Accepts: TEXT, NUMBER, DATE, SELECT, BOOLEAN, FILE, MULTI_FILE

Structured Data — structured_data

Takes tabular or structured input and returns organised, structured output.

Accepts: FILE, MULTI_FILE, TEXT, NUMBER, DATE, SELECT, BOOLEAN

Research & Intelligence — research_intelligence

Reads public web pages you point it at and reports what it found, with sources.

Accepts: URL, TEXT, NUMBER, DATE, SELECT, BOOLEAN

Tool-using Agent — tool_using_agent

Works through a task in steps, choosing which of its tools to use as it goes.

Accepts: URL, TEXT, NUMBER, DATE, SELECT, BOOLEAN

Worker types that are coming soon

These are named in the platform so you know where it is going. None of them can be published. There is no runtime behind them, so a definition naming one is refused when you import it, and a draft using one cannot be submitted.

TypeStatus
Image Generation — image_generationWill produce images from a brief.
Audio — audioWill accept and produce audio.
Video — videoWill accept and produce video.
Code & Software — code_softwareWill write and run code against a task.
Web & Browser — web_browserWill operate a browser to complete a task.
Automation / Actions — automation_actionsWill take actions in other systems, with approval.
Workflow / Worker Teams — workflow_teamsWill let several workers run as one job.
Autonomous / Environment — autonomous_environmentWill work over long horizons in a persistent environment.
If your idea needs one of these, the honest answer today is that BotUp cannot run it. Building the listing anyway wastes your time at review.

Inputs — what you may ask a buyer for

Input typeUse it when
TEXTUsed when the buyer types or pastes something — instructions, notes, a draft, a description.
NUMBERUsed for amounts, quantities and percentages the worker needs to calculate with.
DATEUsed for reporting periods, cut-off dates and time-based filtering.
SELECTUsed when only a fixed set of answers makes sense. The buyer picks one.
BOOLEANUsed for a single decision that changes how the work is done.
URLUsed when the worker reads a public page the buyer names. The buyer is told before purchase and grants permission per run.
FILEUsed when the buyer supplies a document or dataset. Text formats only — CSV, JSON, Markdown and plain text are read as text.
MULTI_FILEUsed when the buyer supplies more than one file of the same kind — several invoices, several exports.

Each input declares an id (lowercase letters, digits and underscores — this is what you reference in instructions), a name and a purpose the buyer reads, whether it is required, and its constraints.

File formats BotUp can read

A FILE or MULTI_FILE input names the formats it accepts. You may only declare formats the platform can actually read — that rule is enforced, and it is why a listing never promises something it cannot deliver.

FormatWhat your worker receives
CSV (.csv)

A table — rows and columns, with the sheet names where there are several.

text/csv

TSV (.tsv)

A table — rows and columns, with the sheet names where there are several.

text/tab-separated-values

Excel spreadsheet (.xlsx)

A table — rows and columns, with the sheet names where there are several.

application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

OpenDocument spreadsheet (.ods)

A table — rows and columns, with the sheet names where there are several.

application/vnd.oasis.opendocument.spreadsheet

Word document (.docx)

A document — the text, in reading order.

application/vnd.openxmlformats-officedocument.wordprocessingml.document

PDF (.pdf)

A document — the text, in reading order.

application/pdf

ZIP archive (.zip)

Each readable file inside, kept separate and named, so your worker can tell January from February.

application/zip

Plain text (.txt)

Text, exactly as written.

text/plain

Markdown (.md)

Text, exactly as written.

text/markdown

JSON (.json)

Text, exactly as written.

application/json

Your worker never learns which format arrived. A spreadsheet, a CSV and a tab-separated export all reach it as a table; a PDF and a Word file both reach it as a document. That is deliberate — it means a worker you write today still works when your buyer switches tools.

Limits that apply to every file input:

  • Up to 5 MB per file.
  • Up to 10 files on a MULTI_FILE input.
  • A ZIP may hold up to 50 readable files. Archives inside archives are not read.
  • Anything inside a ZIP is identified by its contents, not its name — so a file named .xlsx that is really a PDF is read as a PDF.

Formats BotUp recognises but cannot read

These are detected precisely, so a buyer uploading one is told what their file is rather than that it is broken. You cannot declare them.

FormatWhy, and what to tell your buyer
Word 97–2003 (.doc)The old binary Word format. Ask buyers to save as .docx or PDF.
Excel 97–2003 (.xls)The old binary Excel format. Ask buyers to save as .xlsx or CSV.
Apple Pages (.pages)Modern Pages stores its content in a private, undocumented format that changes between releases. Ask buyers to export as PDF or Word — two clicks in Pages.
Apple Numbers (.numbers)Same as Pages. Ask buyers to export as Excel or CSV — two clicks in Numbers.
PowerPoint fileRecognised, and refused with that name.
OpenDocument text documentRecognised, and refused with that name.
RTF documentRecognised, and refused with that name.
compressed archiveRecognised, and refused with that name.

Outputs — what the buyer receives

Output typeFormats
Document — DOCUMENT

A written document with a title and headed sections.

format: docx · coming: PDF

Table — TABLE

Rows and columns. Every row has the same shape.

format: csv, xlsx

Structured data — STRUCTURED_DATA

Machine-readable output for another system to consume.

format: json

Report in BotUp — WEB_REPORT

The result a buyer reads on the page, with no download.

format: web

Declare at least one. Each output’s id becomes a section your instructions address.

Your files are named from your outputs

You do not declare files separately. Every output with a file format produces one, named from the output’s id and format:

Declared outputFile the buyer downloads
"id": "findings", "type": "TABLE", "format": "csv"findings.csv
"id": "summary", "type": "DOCUMENT", "format": "docx"summary.docx
"id": "extracted_rows", "type": "STRUCTURED_DATA", "format": "json"extracted-rows.json
So the way to control what a buyer’s download is called is to name the output well. The id is lowercased and hyphenated to make the filename.

Why sections and artifacts are not in your definition

You may see these two on a worker exported from BotUp. They are the original way of declaring a result, from before typed outputs existed:

"sections":  [ { "key": "result", "label": "Result" } ],
"artifacts": [ { "filename": "summary.md", "mimeType": "text/markdown" } ],
"outputs":   []
A worker that declares outputs ignores both of them entirely. The runtime takes one path or the other: when outputs is non-empty it uses that and derives the files from it; only when outputs is empty does it fall back to sections and artifacts. Filling them in alongside outputs has no effect.

They are still accepted and still readable, because a worker published before typed outputs existed keeps producing exactly what its buyers agreed to. Write outputs for anything new and leave these two out.

Instructions

Instructions are written as one block per output, headed by that output’s id:

## exceptions
Compare {{statement}} against {{ledger}}…

## summary
Three to six sentences…
  • {{input_id}} is replaced with what the buyer supplied.
  • Instructions are configuration, not content. The buyer never sees them.
  • They cannot override platform rules, reveal system prompts, or grant a tool the worker did not declare.
  • Be specific about the shape of the answer. "Return one row per unmatched line with these columns" produces a usable table; "reconcile the accounts" does not.

Choosing a model

A worker may pin the model it runs on, or leave the choice to BotUp. Leaving it out is the default and usually the right answer — the platform’s recommendation improves over time, and a worker that pinned a model in March keeps running March’s model forever.

"model": { "providerId": "anthropic", "modelId": "claude-opus-5" }

Pin one when the choice is part of the product — a cheaper model to protect a thin margin, or a specific one you have tested against.

Available hereIdentifier
Claude Opus 5 — recommendedanthropic:claude-opus-5
Claude Sonnet 5anthropic:claude-sonnet-5
Claude Haiku 4.5anthropic:claude-haiku-4-5
GPT-5openai:gpt-5
GPT-5 miniopenai:gpt-5-mini
Two gates stand between a model existing and your being able to pin it, and both must be open: the model registry must offer it, and its provider must be configured and enabled on this deployment. A model that clears only one appears nowhere — so the list above is the complete answer, whatever else you may have read.

The builder shows what pinning a model does to your earnings before you publish, and warns you when the model would take a material share of the price.

Pricing, and what you actually earn

Execution cost comes out of the price before your share is calculated, so a cheaper model is money in your pocket. A real run of the $5.00 worker on this marketplace:

StepAmount
Buyer pays500¢
Execution cost−4¢ — what the model actually cost
Worker pool496¢
Platform commission (20%)−99¢
You earn397¢
The builder shows this projection for your own price and model before you publish, and warns you if the model would take a material share of the price.

Build your definition

Three fields have to match values this marketplace knows: workerType, category and subcategory. Worker types are the same everywhere; categories are created by an administrator and differ between marketplaces, so no document can list yours reliably.

Choose them here and the definition below is written with the right keys.

5 models are available here. Leaving it unset means your worker follows the platform's recommendation as it changes.

A Document & Text worker may ask for: TEXT, NUMBER, DATE, SELECT, BOOLEAN, FILE, MULTI_FILE.

{
  "schemaVersion": 1,
  "workerType": "document_text",
  "category": "accounting-finance",
  "name": "Name your worker",
  "promise": "One sentence saying exactly what a buyer receives when they run this.",
  "audience": "Who this is for, in their own words.",
  "deliverable": "What arrives at the end, named plainly.",
  "capabilities": "What it reads, what it checks, and what it produces.",
  "limitations": "What it will not do. A limitation you name is a refund you avoid.",
  "turnaround": "Under two minutes",
  "refundNote": "If the run fails or the output is unusable, request a refund within 7 days.",
  "pricing": {
    "unit": "PER_RUN",
    "priceCents": 1000
  },
  "caps": {
    "maxDurationSec": 180,
    "maxCostCents": 60
  },
  "tools": [],
  "inputs": [
    {
      "id": "source_file",
      "name": "Your file",
      "purpose": "The document or spreadsheet to work from",
      "type": "FILE",
      "required": true,
      "help": "Export from your system. One file, one period.",
      "description": "",
      "examples": [],
      "constraints": {
        "accept": [
          "text/csv",
          "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
          "application/vnd.oasis.opendocument.spreadsheet"
        ],
        "maxBytes": 5000000
      }
    },
    {
      "id": "context",
      "name": "Anything we should know",
      "purpose": "Context that changes how the work should be done",
      "type": "TEXT",
      "required": false,
      "help": "Leave blank if there is nothing specific.",
      "description": "",
      "examples": [],
      "constraints": {
        "maxLength": 2000,
        "multiline": true
      }
    }
  ],
  "outputs": [
    {
      "id": "findings",
      "name": "Findings",
      "type": "TABLE",
      "format": "csv",
      "required": true
    },
    {
      "id": "summary",
      "name": "Summary",
      "type": "DOCUMENT",
      "format": "markdown",
      "required": true
    }
  ],
  "instructions": "## findings\nWork through {{source_file}} and return one row per finding.\nState the columns you want, in order, and what each one holds.\n\n## summary\nThree to six sentences. Say what was found and what to do first.\nDo not speculate beyond what the input shows.",
  "demo": {
    "enabled": false,
    "fixture": {}
  },
  "sampleOutput": {}
}
Categories on this marketplace right now: accounting-finance, market-intel, content-ops, marketing-growth, sales-ops, back-office, operations, customer-insight, people-hr, legal-compliance, data-reporting. If you are looking at a definition written for a different BotUp, its category may not exist here — the importer will ask you to pick one.

A complete definition

An account reconciliation worker: two file inputs, an optional date, a table and a document out. Copy it, change the fields, import it.

{
  "schemaVersion": 1,
  "workerType": "structured_data",
  "category": "accounting-finance",
  "subcategory": "bank-reconciliation",
  "name": "Account Reconciliation",
  "promise": "Match a bank statement against your ledger and list every line that does not agree.",
  "audience": "Bookkeepers and finance leads at companies of 10 to 200 people.",
  "deliverable": "A table of unmatched lines, and a short written summary of what to check first.",
  "capabilities": "Reads a statement and a ledger as a spreadsheet, CSV or PDF. Matches on date, amount and reference. Flags anything unmatched, duplicated, or matched only approximately.",
  "limitations": "Does not connect to your bank. Does not post journal entries. Does not decide whether a difference is acceptable — it tells you where they are.",
  "turnaround": "Under two minutes",
  "refundNote": "If the run fails or the output is unusable, request a refund within 7 days.",
  "pricing": {
    "unit": "PER_RUN",
    "priceCents": 1500
  },
  "caps": {
    "maxDurationSec": 180,
    "maxCostCents": 60
  },
  "tools": [],
  "inputs": [
    {
      "id": "statement",
      "name": "Bank statement",
      "purpose": "The transactions your bank recorded",
      "type": "FILE",
      "required": true,
      "help": "Export from your bank as CSV, Excel or PDF. One account, one period.",
      "examples": [],
      "description": "",
      "constraints": {
        "accept": [
          "text/csv",
          "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
          "application/vnd.oasis.opendocument.spreadsheet",
          "application/pdf"
        ],
        "maxBytes": 5000000
      }
    },
    {
      "id": "ledger",
      "name": "Your ledger",
      "purpose": "What your books say for the same period",
      "type": "FILE",
      "required": true,
      "help": "Export from your accounting system covering the same dates as the statement.",
      "examples": [],
      "description": "",
      "constraints": {
        "accept": [
          "text/csv",
          "text/tab-separated-values",
          "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        ],
        "maxBytes": 5000000
      }
    },
    {
      "id": "period",
      "name": "Period ending",
      "purpose": "The closing date being reconciled",
      "type": "DATE",
      "required": false,
      "help": "Leave blank to use the latest date found in the files.",
      "examples": [],
      "description": "",
      "constraints": {}
    }
  ],
  "outputs": [
    {
      "id": "exceptions",
      "name": "Unmatched lines",
      "type": "TABLE",
      "format": "csv",
      "required": true
    },
    {
      "id": "summary",
      "name": "What to check first",
      "type": "DOCUMENT",
      "format": "markdown",
      "required": true
    }
  ],
  "sections": [],
  "artifacts": [],
  "instructions": "## exceptions\nCompare {{statement}} against {{ledger}} for the period ending {{period}}.\n\nMatch on date, amount and reference. A line matches when the amount is identical\nand the date is within three days.\n\nReturn one row per unmatched line with these columns: source, date, description,\namount, reason. \"source\" is either \"statement\" or \"ledger\". \"reason\" is one of\n\"no match\", \"amount differs\", \"duplicate\", or \"date outside window\".\n\n## summary\nThree to six sentences. State the number of unmatched lines, the total value on\neach side, and the single item most likely to explain the difference. Do not\nspeculate beyond what the files show. If everything reconciles, say so plainly.",
  "demo": {
    "enabled": true,
    "fixture": {
      "statement": "date,description,amount\n2026-01-04,Invoice 118,1240.00\n2026-01-09,Refund,-84.50\n",
      "ledger": "date,description,amount\n2026-01-04,INV-118 Northwind,1240.00\n",
      "period": "2026-01-31"
    }
  },
  "sampleOutput": {
    "exceptions": "source,date,description,amount,reason\nstatement,2026-01-09,Refund,-84.50,no match\n",
    "summary": "One line of 2 unmatched, worth -$84.50. The statement shows a refund on 9 January with no matching ledger entry. Check whether the credit note was posted."
  }
}
schemaVersion must be 1. A file written for a newer version of BotUp is refused rather than partly imported.

Fields a definition may not set

A definition describes a worker. It cannot describe its standing on the marketplace, and naming one of these is an error rather than something quietly ignored:

  • reviewState, publishedAt — review is the platform’s decision.
  • creatorAccountId — a worker belongs to whoever imports it.
  • testPassedAt — you run the test.
  • versionNumber, slug — assigned when the draft is created.

From a file to a published worker

  1. 1ImportPaste the definition. A draft is created with everything filled in.
  2. 2Review the contractOpen the draft and check the inputs, outputs and instructions read the way you intended.
  3. 3Run a testUse the generated scaffolding or your own input. You see the output, the cost and any errors before a buyer would.
  4. 4Add a demo and a sample outputBoth are optional and both markedly improve conversion. A buyer who can see one result is far likelier to buy one.
  5. 5SubmitThe gate lists anything missing. Fix it and submit again — there is no penalty for resubmitting.
  6. 6PublishOnce approved, publishing makes the listing purchasable. You can unpublish at any time.

Rules that apply however you build

  • Only declare formats and worker types the platform can run. This is enforced, not advisory.
  • State what the worker will not do. A limitation you name is a refund you avoid.
  • No accuracy claims you cannot evidence — no "99% accurate", no "guaranteed".
  • A demo must use safe fixture data. It runs without a buyer’s files and must not need them.
  • Read the prohibited uses and the publishing guidelines before submitting.
NextPre-submission checklistThe questions review will ask. Ask them yourself first.