Skip to content

Listing

All of these need a wallet session. A seller can only see and change their own packages.

The flow is: save a draft, run the scan, mint from your wallet, confirm the mint.

Save a draft

POST /api/package/save
json
{
  "id": 12,
  "name": "4 to 70 characters",
  "kind": "skill",
  "category": "payments",
  "priceUsdg": 3,
  "sellerName": "The name you sell under",
  "summary": "60 to 500 characters",
  "body": "200 to 60,000 characters"
}

Leave out id to create a new draft. Include it to update one.

FieldRules
name4 to 70 characters
kindskill, prompt, mcp, workflow or code
categorypayments, onchain, research, coding, devops, data, content, security or other
priceUsdg0.10 to 500
sellerNameAt least 2 characters. Cut to 40
summary60 to 500 characters. This is the free summary
body200 to 60,000 characters. This is the package itself

Text fields are trimmed, and Windows line endings in body are converted.

Returns { "id": 12 }.

  • Any edit resets the package to draft, so it has to be scanned again.
  • A live package can't be edited (409).
  • At most 20 new drafts per wallet per day (429).
StatusError
400"The name must be 4 to 70 characters."
400"Add the name you sell under."
400"Pick what kind of package this is."
400"Pick a category."
400"The free summary must be 60 to 500 characters."
400"The package needs at least 200 characters. Stubs aren't listed."
400"The package is too long. The limit is 60,000 characters."
400"The price must be between 0.10 and 500 USDG."
401"Sign in to list a package."
404"Package not found." The id isn't one of your packages
409"A live package can't be edited."
429"You've created a lot of drafts today. Try again tomorrow."

Run the scan

POST /api/package/audit
{ "id": 12 }
json
{
  "status": "approved",
  "audit": {
    "verdict": "approve",
    "score": 92,
    "summary": "…",
    "issues": [{ "severity": "note", "check": "commands", "detail": "…" }],
    "engine": "…",
    "auditedAt": "…"
  },
  "metaUrl": "https://agentware.sh/api/meta/12"
}

status is approved, revise or rejected. issues[].severity is blocker, fix or note. issues[].check is usually one of injection, exfiltration, commands, wallet, honesty, originality or quality. See The security scan.

On approval the package gets its public slug and its content fingerprint. A scan lowers risk. It is not a guarantee.

StatusWhen
404"Package not found."
409"This package is already live."
429"This package has been scanned too many times. Start a new draft." The limit is 8 scans per package
503The scan agent is switched off or unavailable. The draft stays saved

Mint

Minting is done by the seller's own wallet, not by the API. Call the ERC-8004 identity registry:

register(metaUrl)   on 0x8004A169FB4a3325136EB29fA0ceB6D2e539a432

using the metaUrl from the scan response.

Confirm the mint

POST /api/package/minted
{ "id": 12, "txHash": "0x…" }
json
{ "slug": "the-package-name-12", "packageId": 322 }

The server checks that the transaction succeeded, was sent by the signed-in wallet, minted an identity to that wallet, and that the identity points to this package's metaUrl. Only then does the package go live. Calling it again for a live package returns the same result.

After the package goes live, the scan agent's wallet can post the verdict onchain. When it does, the package's auditTx is set.

StatusWhen
400"A transaction hash is required."
400"That transaction hasn't succeeded yet. Wait a few seconds and try again."
400"No package was minted in that transaction."
400"That mint points to a different package."
403"That transaction was sent from a different wallet."
409"This package hasn't passed the scan."
409"That mint is already linked to another package."

Your packages

GET /api/me/dashboard
json
{
  "packages": [{ "…package fields…": "…", "status": "live", "earnedUsdg": 18.9, "updatedAt": "…" }],
  "totals": { "earnedUsdg": 18.9, "live": 1, "sales": 7 }
}

Each entry has the package fields plus status, earnedUsdg and updatedAt. status is one of draft, revise, rejected, approved, live. earnedUsdg is the seller's 90% share of completed sales.

GET /api/me/package/{id}
json
{
  "package": { "…package fields…": "…", "status": "approved", "body": "The package…" },
  "audit": { "…latest scan report, or null…": "…" },
  "metaUrl": "https://agentware.sh/api/meta/12"
}

One of your packages with its full text, latest scan report and metaUrl. {id} is the database id.

A scan lowers risk. It is not a guarantee. Review a package before your agent runs it.