Your own Service

The running jobjob_7Hq2 · accepted · document.fr-CA.pdf · $49.00 final

Add the work you sell to your brand, brief the AI that does it, check it until it's ready, and sell it on every surface.

In the same folder, init adds a second Service to your brand:

Terminal
$ npx services.dev init "Store Listing"
  wrote   services/store-listing.ts · services/store-listing.md
  kept    package.json · AGENTS.md
  next    npx services.dev dev

Fill in what comes in, what goes out and the price. Here is Store Listing, finished:

TypeScript
import { Service } from 'services.dev'

export default Service({
  name: 'Store Listing',
  description: 'Your app store listing, written for each language you sell in.',
  input: { app: 'text: what the app does, such as a budgeting app for couples', languages: 'language[]: such as fr, de, ja', tone: ['plain', 'playful'] },
  output: { listing: 'file' },
  price: 29,
})

languages is a list, and tone is a list of choices. The such as in each field is what an agent sends when it tries the Service.

The brief is your know-how, and the AI reads it on every job. init writes the questions. Answer them the way you'd brief someone new:

Markdown
# Store Listing

The AI reads this brief on every job. Write it the way you'd brief someone new.

## How the work is done

- Read what the app does, then write a title, a subtitle, keywords and a description in each language.
- Write each language fresh, the way a native speaker would, never word for word from English.
- Count every field against the store's limit before you call the job done.

## What good looks like

- A title a buyer would type into the store's search, in their own language.
- The tone the buyer chose, in every language.

## Never

- Never claim a feature the app doesn't have.
- Never name a competitor.

Say your first description ran long:

Terminal
$ npx services.dev check
services/store-listing.ts · 5 lines · $29 per job, within 48 hours, charged on delivery.
  who     AI delivers every job.
  steps   draft · ai → review · ai · adversarial
  agent   order_store_listing · 45 of 30 words · bought job_7Hq2 · $29.00 · no person
  ledger  +$29.00 · AI $0.84 (example) · you $28.16
  margin  at least $23.20 a job (80%) · a job that stops costs you at most $5.80
  apps    customer portal · owner console
  ✗ The tool description is over 30 words, so agents skim past it. Shorten description: the tool description is 45 words.
    https://services.dev/docs/reference/check/description_too_long

Each failure says why, what to do next, and where it's explained. Shorten it, and run check again:

Terminal
$ npx services.dev check
services/store-listing.ts · 5 lines · $29 per job, within 48 hours, charged on delivery.
  who     AI delivers every job.
  steps   draft · ai → review · ai · adversarial
mcp     14 buyer tools · 5,133 of 8,000 tokens · 9 more with ?toolset=sandbox
  agent   order_store_listing · 24 of 30 words · bought job_7Hq2 · $29.00 · no person
  ledger  +$29.00 · AI $0.84 (example) · you $28.16
  margin  at least $23.20 a job (80%) · a job that stops costs you at most $5.80
  apps    customer portal · owner console

services/translation.ts · 4 lines · $49 per job, within 48 hours, charged on delivery.
  who     AI delivers every job.
  steps   draft · ai → review · ai · adversarial
  agent   order_translation · 24 of 30 words · bought job_7Hq2 · $49.00 · no person
  ledger  +$49.00 · AI $0.84 (example) · you $48.16
  margin  at least $39.20 a job (80%) · a job that stops costs you at most $9.80
  apps    customer portal · owner console

mcp     14 buyer tools · 5,105 of 8,000 tokens · 9 more with ?toolset=sandbox
✓ ready to sell · 2 Services · AI delivers both alone · each keeps at least 80% of every job

Every check has an agent buy a job, so you know agents can before a buyer tries.

Stop dev, and start it again with npx services.dev dev --no-try, so no agent orders first. Then order Store Listing and wait for it, on whichever surface you like:

$ npx services.dev store-listing "app=a budgeting app for couples" languages=fr,de tone=plain --max 29 --key listing
job_7Hq2 · working · $29.00 held
job_7Hq2 · delivered · listing.txt · $29.00 charged
  record  draft · ai | review · ai · pass
  ledger  +$29.00 · AI $0.84 · you $28.16
  next    npx services.dev accept job_7Hq2
$ curl -X POST http://localhost:8787/jobs -H 'content-type: application/json' -d '{"service":"store-listing","app":"a budgeting app for couples","languages":["fr","de"],"tone":"plain","max_usd":29,"key":"listing"}'
← 202 · job_7Hq2 · working · $29.00 held
  next    get_job {"id":"job_7Hq2"}
$ curl http://localhost:8787/jobs/job_7Hq2?wait=50
← 200 · job_7Hq2 · delivered · listing.txt · $29.00 charged
  next    accept_job {"id":"job_7Hq2"}
→ tools/call order_store_listing {"app":"a budgeting app for couples","languages":["fr","de"],"tone":"plain","max_usd":29,"key":"listing"}
← job_7Hq2 · working · $29.00 held
  next    get_job {"id":"job_7Hq2"}
→ resources/read job://job_7Hq2?wait=50
← job_7Hq2 · delivered · listing.txt · $29.00 charged
  next    accept_job {"id":"job_7Hq2"}
await lingua.storeListing.order({"app":"a budgeting app for couples","languages":["fr","de"],"tone":"plain","max_usd":29,"key":"listing"})
← job_7Hq2 · working · $29.00 held
  next    get_job {"id":"job_7Hq2"}
await lingua.jobs.wait("job_7Hq2")
← job_7Hq2 · delivered · listing.txt · $29.00 charged
  next    accept_job {"id":"job_7Hq2"}

You never wrote a route, a command, a tool or an SDK call. Each one comes from the Service: one file, every surface.