REST API reference

Complete reference for all mog.md REST API endpoints.

The mog REST API is available at https://api.mog.md. All endpoints are under /v1/. Requests and responses are JSON unless otherwise noted.

Base URL

https://api.mog.md

Authentication

Protected endpoints require a Bearer token in the Authorization header:

Authorization: Bearer <token>

Tokens are issued via the device code flow or retrieved from your dashboard. Different endpoints require different scopes:

ScopeRequired for
readEntitlements, reviews
purchasePurchases
downloadDownload URLs
sellVendor operations, uploads

Errors

Errors return a JSON body with a message field:

{ "message": "Listing not found" }
StatusMeaning
400Bad request / validation error
401Missing or invalid token
402Payment / approval required
403Insufficient token scope
404Resource not found
422Unprocessable entity
429Rate limit exceeded
500Internal server error

Health

GET /health

Returns API health status. No authentication required.

// All services healthy — HTTP 200
{
  "ok": true,
  "version": "0.1.6",
  "status": "healthy"
}
 
// Degraded — HTTP 503
{
  "ok": false,
  "version": "0.1.6",
  "status": "degraded"
}

When status is "degraded", the HTTP status code is 503. Use this endpoint for liveness/readiness probes in your deployment platform.


Authentication endpoints

Start device flow

POST /v1/auth/device/start

Initiates a device code flow.

Response:

{
  "deviceCode": "internal-device-code",
  "userCode": "XKCD-7Z4B",
  "verificationUri": "https://mog.md/device",
  "expiresIn": 900,
  "interval": 5
}

Poll device flow

POST /v1/auth/device/poll

Poll for approval. Call every interval seconds.

Request body:

{ "deviceCode": "internal-device-code" }

Response:

// Still waiting
{ "status": "authorization_pending" }
 
// Code expired
{ "status": "expired" }
 
// Approved — store this token
{
  "status": "approved",
  "token": "mog_...",
  "tokenType": "Bearer",
  "expiresIn": 31536000
}

Approve device code

POST /v1/auth/device/approve — Auth: Bearer token

Request body:

{ "userCode": "XKCD-7Z4B" }

Response:

{ "ok": true }

Revoke token

POST /v1/auth/token/revoke — Auth: Bearer token

{ "ok": true }

List API tokens

GET /v1/auth/tokens — Auth: Bearer token

Returns all active tokens for the current user.

{
  "tokens": [
    {
      "id": "uuid",
      "name": "CLI device token",
      "scopes": ["read", "purchase", "download"],
      "policyId": null,
      "policyName": null,
      "lastUsedAt": "2026-01-15T10:00:00.000Z",
      "expiresAt": null,
      "revokedAt": null,
      "createdAt": "2026-01-01T00:00:00.000Z"
    }
  ]
}

Revoke token by ID

DELETE /v1/auth/tokens/:id — Auth: Bearer token

{ "ok": true }

GET /v1/search

Search packages. No authentication required.

Query parameters:

ParameterTypeDescription
qstringFull-text search query
typeskill | rule | bundle | template | mcpFilter by package type
targetcursor | claude-code | codex | gemini-cli | windsurf | genericFilter by agent target
sortpopular | recent | rated | price_asc | price_desc | trustedSort order (default: popular). trusted ranks by trust metrics.
pagenumberPage number (default: 1, ignored when cursor is set)
per_pagenumberResults per page (1–50, default: 20)
freebooleanOnly free packages
toolstringFilter by MCP tool name (GIN index)
tagsstringComma-separated tag filter
livebooleanOnly listings with a registered service endpoint
protocolmcp | a2a | https | acpFilter by service protocol
settlementstringFilter by settlement method (e.g. stripe_mpp)
verifiedbooleanOnly verified vendors
cursorstringCursor from a previous response for efficient keyset pagination

Response:

{
  "results": [
    {
      "id": "uuid",
      "vendorSlug": "acme",
      "slug": "router-eval",
      "title": "Router Eval Skill",
      "description": "...",
      "type": "skill",
      "tags": ["react", "testing"],
      "targets": ["cursor", "claude-code"],
      "priceCents": 0,
      "currency": "usd",
      "latestVersion": "1.0.0",
      "installCount": 42,
      "mogRating": "4.8",
      "vendorName": "Acme Corp",
      "vendorVerified": false
    }
  ],
  "total": 1,
  "page": 1,
  "perPage": 20,
  "nextCursor": null
}

When paginating with cursor, pass the nextCursor value from the previous response as the cursor query parameter. When cursor is used, total and page are null — only nextCursor and perPage are set.


Listings

Get listing

GET /v1/listings/:vendor/:slug

Get a single listing by vendor slug and package slug. No authentication required.

Get releases

GET /v1/listings/:vendor/:slug/releases

{
  "releases": [
    {
      "id": "uuid",
      "version": "1.1.0",
      "archiveSha256": "a3f8...",
      "publishedAt": "2026-01-15T10:00:00.000Z"
    }
  ]
}

Reviews

Get reviews

GET /v1/listings/:vendor/:slug/reviews

{
  "reviews": [
    {
      "id": "uuid",
      "userId": "uuid",
      "rating": 5,
      "body": "Excellent skill, saved me hours.",
      "createdAt": "2026-01-10T08:00:00.000Z"
    }
  ],
  "rating": 4.8,
  "ratingCount": 12
}

Create or update review

POST /v1/listings/:vendor/:slug/reviews — Auth: read scope

Request body:

{
  "rating": 5,           // required: 1–5
  "body": "Great skill!" // optional: max 2000 chars
}

Vote on review

POST /v1/listings/:vendor/:slug/reviews/:id/vote — Auth: read scope

Request body:

{ "helpful": true }
{ "ok": true }

Purchases & entitlements

Purchase a listing

POST /v1/purchases — Auth: purchase scope

Request body:

{
  "listingId": "uuid",          // required
  "releaseId": "uuid",          // optional: defaults to latest published release
  "maxPriceCents": 1000,        // optional: spend ceiling
  "useWallet": false,           // optional: deduct from wallet balance instead of card
  "orgSlug": "my-org",          // optional: use org wallet instead of personal wallet
  "channel": "api"              // optional: "api" (default) or "web"
}

Response (one of four shapes):

// Purchased (free or wallet)
{
  "status": "purchased",
  "entitlementId": "uuid",
  "orderId": "uuid",
  "amountCents": 500,
  "walletBalanceCents": 4500    // only present for wallet purchases
}
 
// Already owned
{ "status": "already_owned", "entitlementId": "uuid" }
 
// Approval required — HTTP 402
{
  "status": "approval_required",
  "approvalUrl": "https://mog.md/purchases/approve?listing=...",
  "reason": "Price (1500¢) exceeds your policy limit (1000¢)"
}
 
// Insufficient wallet balance — HTTP 402
{
  "status": "insufficient_balance",
  "balanceCents": 200,
  "requiredCents": 500
}

List entitlements

GET /v1/entitlements — Auth: read scope

{
  "entitlements": [
    {
      "id": "uuid",
      "listingId": "uuid",
      "releaseId": "uuid",
      "vendorSlug": "acme",
      "listingSlug": "router-eval",
      "listingTitle": "Router Eval Skill",
      "version": "1.0.0",
      "grantedAt": "2026-01-15T10:00:00.000Z"
    }
  ]
}

Check entitlement

GET /v1/entitlements/:listingId — Auth: read scope

// Owned — HTTP 200
{ "owned": true, "entitlement": { "...": "..." } }
 
// Not owned — HTTP 404
{ "owned": false }

List orders

GET /v1/orders — Auth: read scope

Returns the current user's order history. Supports ?paymentIntentId=<id> query param to look up a specific order by Stripe payment intent (used for checkout success polling).

{
  "orders": [
    {
      "id": "uuid",
      "listingId": "uuid",
      "releaseId": "uuid",
      "amountCents": 500,
      "status": "paid",
      "fundingSource": "wallet",
      "createdAt": "2026-01-15T10:00:00.000Z",
      "vendorSlug": "acme",
      "vendorName": "Acme Corp",
      "listingSlug": "router-eval",
      "listingTitle": "Router Eval Skill",
      "version": "1.0.0"
    }
  ]
}

Downloads

Get download URL

POST /v1/downloads — Auth: download scope

Request body:

{ "releaseId": "uuid" }

Response:

{
  "url": "https://...signed-url...",
  "sha256": "a3f8c2d1...",
  "expiresAt": "2026-01-15T10:05:00.000Z"
}

User

Get current user

GET /v1/users/me — Auth: Bearer token

{
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "name": "Ada Lovelace",
    "avatarUrl": "https://...",
    "emailVerified": true,
    "createdAt": "2026-01-01T00:00:00.000Z"
  }
}

Update profile

PATCH /v1/users/me — Auth: Bearer token

Request body (all fields optional):

{
  "name": "Ada Lovelace",
  "avatarUrl": "https://..."
}

Delete account

DELETE /v1/users/me — Auth: Bearer token

Soft-deletes the user account: all personally identifiable information (name, email, avatar) is anonymized, and all active API tokens are revoked immediately. The anonymized record is retained for financial audit trail integrity. This action is irreversible.

{ "ok": true }

Vendor

Create or update vendor profile

POST /v1/vendor/profile — Auth: sell scope

Request body:

{
  "slug": "acme",              // 2–32 chars, lowercase letters/numbers/hyphens
  "displayName": "Acme Corp",  // 1–64 chars
  "bio": "We make skills.",    // optional, max 500 chars
  "website": "https://acme.io" // optional, must be valid URL
}

Start Stripe Connect onboarding

POST /v1/vendor/onboard — Auth: sell scope

{ "url": "https://connect.stripe.com/setup/..." }

Upload release

POST /v1/vendor/releases — Auth: sell scope

Request: multipart/form-data with:

FieldTypeDescription
archivefile (.zip)Package archive
priceCentsnumberPrice in cents (0 for free)

Response:

{
  "release": {
    "id": "uuid",
    "version": "1.0.0",
    "scanStatus": "pending",
    "createdAt": "2026-01-15T10:00:00.000Z"
  },
  "listing": { "id": "uuid", "slug": "my-skill" }
}

Publish release

PATCH /v1/vendor/releases/:id/publish — Auth: sell scope

{ "ok": true, "version": "1.0.0" }

Update listing

PATCH /v1/vendor/listings/:id — Auth: sell scope

Request body (all fields optional):

{
  "title": "My Awesome Skill",  // 1–120 chars
  "description": "...",          // 1–1024 chars
  "tags": ["react", "testing"],  // max 10 tags
  "priceCents": 500,             // 0 = free
  "readmeMd": "# My Skill\n...", // raw Markdown for listing page
  "status": "published"         // optional: "published" | "unlisted" | "draft"
}

Get vendor analytics

GET /v1/vendor/analytics — Auth: sell scope

{
  "vendor": {
    "slug": "acme",
    "displayName": "Acme Corp",
    "stripeOnboardingComplete": true
  },
  "revenue": {
    "totalCents": 15000,
    "totalOrders": 42
  },
  "listings": [
    {
      "id": "uuid",
      "slug": "router-eval",
      "title": "Router Eval Skill",
      "priceCents": 500,
      "installCount": 42,
      "orderCount": 38,
      "revenueCents": 14250
    }
  ]
}

Vendor verification

Get verification status

GET /v1/vendor/verification — Auth: sell scope

{
  "domainVerified": false,
  "githubVerified": true,
  "githubOrg": "acme-corp",
  "verified": true
}

Start domain verification

POST /v1/vendor/verify/domain — Auth: sell scope

Returns a DNS TXT record to add to your domain for verification.

{ "record": "mog-verify=a1b2c3d4e5f6..." }

Check domain verification

POST /v1/vendor/verify/domain/check — Auth: sell scope

Checks whether the DNS TXT record is live.

{ "verified": true }

Start GitHub org verification

GET /v1/vendor/verify/github — Auth: sell scope

Redirects to GitHub OAuth to verify ownership of a GitHub org. Returns { "url": "https://github.com/login/oauth/authorize?..." }.

Signing keys

Used by mog publish to sign package archives. Buyers can verify publisher authenticity.

List signing keys

GET /v1/vendor/keys — Auth: sell scope

{
  "activeKey": {
    "publicKey": "-----BEGIN PUBLIC KEY-----\n...",
    "fingerprint": "a1b2c3d4e5f6a7b8"
  },
  "log": [
    {
      "action": "register",
      "fingerprint": "a1b2c3d4e5f6a7b8",
      "createdAt": "2026-01-15T10:00:00.000Z"
    }
  ]
}

Register or rotate signing key

POST /v1/vendor/keys — Auth: sell scope

Request body:

{ "publicKey": "-----BEGIN PUBLIC KEY-----\n...", "fingerprint": "a1b2c3d4e5f6a7b8" }

Response:

{ "action": "register", "fingerprint": "a1b2c3d4e5f6a7b8" }

action is "register" on first key, "rotate" if replacing an existing key.

Revoke signing key

DELETE /v1/vendor/keys/:fingerprint — Auth: sell scope

{ "ok": true }

Reply to review

POST /v1/vendor/reviews/:id/reply — Auth: sell scope

Request body:

{ "body": "Thanks for the feedback! Fixed in v1.1.0." }
{ "ok": true }

Spend policies

Spend policies control what agents can purchase autonomously. See Spend policies for the full reference.

List policies

GET /v1/policies — Auth: Bearer token

{
  "policies": [
    {
      "id": "uuid",
      "name": "CI agent policy",
      "maxPerPurchaseCents": 1000,
      "dailyLimitCents": 5000,
      "monthlyLimitCents": 20000,
      "requireApprovalAboveCents": 500,
      "vendorAllowlist": [],
      "blockedTypes": [],
      "active": true,
      "createdAt": "2026-01-01T00:00:00.000Z"
    }
  ]
}

Create policy

POST /v1/policies — Auth: Bearer token

Request body:

{
  "name": "CI agent policy",          // required, 1–128 chars
  "maxPerPurchaseCents": 1000,         // optional, cents
  "dailyLimitCents": 5000,            // optional
  "monthlyLimitCents": 20000,         // optional
  "requireApprovalAboveCents": 500,   // optional — require user approval above this price
  "vendorAllowlist": [],              // optional — empty = all vendors allowed
  "blockedTypes": ["bundle"],         // optional — block specific package types
  "active": true                      // optional, default: true
}

Update policy

PATCH /v1/policies/:id — Auth: Bearer token

Same fields as create, all optional. Returns updated policy.

Delete policy

DELETE /v1/policies/:id — Auth: Bearer token

{ "ok": true }

Leaderboard

GET /v1/leaderboard

Get the package leaderboard. No authentication required.

Query parameters:

ParameterTypeDescription
windowall | trending | hotRanking window (default: all). all sorts by mogRating; trending and hot sort by recent install velocity.
typeskill | rule | bundle | templateFilter by package type
limitnumberMax results (default: 50, max: 200)
offsetnumberPagination offset
{
  "rankings": [
    {
      "rank": 1,
      "listing": {
        "vendor": "acme",
        "slug": "router-eval",
        "title": "Router Eval Skill",
        "description": "...",
        "type": "skill",
        "targets": ["cursor", "claude-code"],
        "priceCents": 500,
        "currency": "usd",
        "mogRating": 4.8,
        "installCount": 1240,
        "installs24h": 12,
        "installs7d": 87,
        "latestVersion": "1.0.0",
        "vendorName": "Acme Corp",
        "vendorVerified": true
      }
    }
  ],
  "total": 42,
  "totalInstalls": 98230,
  "window": "all",
  "generatedAt": "2026-02-26T00:00:00.000Z"
}

Audits

GET /v1/audits

Get scan/audit results for published packages. No authentication required. Useful for transparency tooling and dashboards.

Query parameters:

ParameterTypeDescription
typestringFilter by package type
statuspassed | flagged | failed | pendingFilter by scan status
limitnumberMax results (default: 20, max: 100)
offsetnumberPagination offset
{
  "audits": [
    {
      "rank": 1,
      "vendor": "acme",
      "slug": "router-eval",
      "title": "Router Eval Skill",
      "type": "skill",
      "vendorVerified": true,
      "mogRating": 4.8,
      "installCount": 124,
      "scan": {
        "status": "passed",
        "label": "safe",
        "qualityScore": 87,
        "version": "1.0.0",
        "scannedAt": "2026-01-15T10:00:00.000Z"
      },
      "promptGuard": {
        "ran": true,
        "verified": true,
        "perFile": [{ "file": "SKILL.md", "label": "BENIGN", "score": 0.99 }]
      }
    }
  ],
  "total": 42,
  "generatedAt": "2026-02-23T18:00:00.000Z"
}

Webhooks

Stripe webhook

POST /v1/webhooks/stripe

Stripe webhook handler. Verifies the stripe-signature header. Handles payment and account lifecycle events.

{ "received": true }

Billing

Buyer billing and payment management.

Spending overview

GET /v1/billing/overview — Auth: Bearer token

Returns aggregate spending stats for the authenticated user.

{
  "allTime": { "totalCents": 5000, "totalOrders": 12 },
  "thisMonth": { "totalCents": 1500 },
  "thisWeek": { "totalCents": 500 },
  "recentOrders": [
    {
      "id": "uuid",
      "amountCents": 500,
      "status": "paid",
      "createdAt": "2026-02-15T10:00:00.000Z",
      "listingTitle": "Router Eval Skill",
      "listingSlug": "router-eval",
      "vendorSlug": "acme"
    }
  ]
}

List payment methods

GET /v1/billing/payment-methods — Auth: Bearer token

{
  "hasStripeCustomer": true,
  "paymentMethods": [
    { "id": "pm_xxx", "brand": "visa", "last4": "4242", "expMonth": 12, "expYear": 2028 }
  ]
}

Create setup intent

POST /v1/billing/setup-intent — Auth: Bearer token

Creates a Stripe SetupIntent for adding a new payment method via the Stripe Payment Element.

{ "clientSecret": "seti_xxx_secret_xxx" }

Create billing portal session

POST /v1/billing/portal-session — Auth: Bearer token

Creates a Stripe Customer Portal session for managing payment methods and invoices.

{ "url": "https://billing.stripe.com/session/..." }

POST /v1/billing/seller-dashboard-link — Auth: sell scope

Creates a Stripe Express Dashboard login link for sellers to view payouts.

{ "url": "https://connect.stripe.com/express/..." }

Seller overview

GET /v1/billing/seller-overview — Auth: sell scope

{
  "isVendor": true,
  "vendor": { "slug": "acme", "displayName": "Acme Corp", "stripeOnboardingComplete": true },
  "allTime": { "grossCents": 15000, "netCents": 13500, "totalSales": 42 },
  "thisMonth": { "grossCents": 5000, "netCents": 4500 }
}

If the user has no vendor profile, returns { "isVendor": false }.


Wallet

Pre-funded wallet balance for frictionless purchases. Top up once; use for any purchase via "useWallet": true in the purchase endpoint.

Get wallet

GET /v1/wallet — Auth: Bearer token

{
  "balanceCents": 4500,
  "autoTopUpEnabled": false,
  "autoTopUpThresholdCents": 500,
  "autoTopUpAmountCents": 2000
}

Top up wallet

POST /v1/wallet/top-up — Auth: purchase scope

Creates a Stripe PaymentIntent. Pass the clientSecret to Stripe's Payment Element. Balance is credited on payment_intent.succeeded.

Request body:

{ "amountCents": 2000 }

Min: 500 ($5.00). Max: 50000 ($500.00).

Response:

{ "clientSecret": "pi_xxx_secret_xxx" }

Configure auto top-up

PATCH /v1/wallet/auto-top-up — Auth: purchase scope

Automatically top up when balance drops below a threshold. Requires a saved payment method.

Request body (all fields optional):

{
  "enabled": true,
  "thresholdCents": 500,
  "amountCents": 2000
}
{
  "autoTopUpEnabled": true,
  "autoTopUpThresholdCents": 500,
  "autoTopUpAmountCents": 2000
}

Wallet transactions

GET /v1/wallet/transactions — Auth: Bearer token

Query parameters: limit (max 100, default 50), cursor (from previous response for keyset pagination).

{
  "transactions": [
    {
      "id": "uuid",
      "type": "purchase",
      "amountCents": -500,
      "balanceAfterCents": 4000,
      "description": "Purchase: acme/router-eval",
      "createdAt": "2026-02-15T10:00:00.000Z"
    }
  ],
  "nextCursor": null,
  "hasMore": false
}

Transaction type values: top_up, purchase, refund, auto_top_up, metered_usage (deducted when calling a live service tool).


Organizations

Organizations let teams share a wallet, spend policies, and private packages.

Create organization

POST /v1/orgs — Auth: Bearer token

Request body:

{ "slug": "acme-team", "name": "Acme Team" }

Returns { "org": { "id": "uuid", "slug": "acme-team", "name": "Acme Team" } } (HTTP 201). Creator becomes owner.

List organizations

GET /v1/orgs — Auth: Bearer token

{
  "orgs": [
    { "id": "uuid", "slug": "acme-team", "name": "Acme Team", "role": "owner", "createdAt": "2026-01-01T00:00:00.000Z" }
  ]
}

Get organization

GET /v1/orgs/:slug — Auth: Bearer token (must be a member)

{
  "org": { "id": "uuid", "slug": "acme-team", "name": "Acme Team", "myRole": "admin" },
  "members": [
    { "userId": "uuid", "role": "owner", "name": "Ada Lovelace", "email": "ada@acme.io" }
  ]
}

Update organization

PATCH /v1/orgs/:slug — Auth: Bearer token (admin or owner)

Request body (all optional): { "name": "...", "avatarUrl": "https://..." }

Delete organization

DELETE /v1/orgs/:slug — Auth: Bearer token (owner only)

{ "deleted": true }

Invite member

POST /v1/orgs/:slug/members — Auth: Bearer token (admin or owner)

Sends an invitation email. Invitations expire after 7 days.

Request body:

{ "email": "new@member.io", "role": "member" }

role options: "admin", "member". Returns { "invitation": { ... } } (HTTP 201).

Accept invitation

POST /v1/orgs/accept-invite — Auth: Bearer token

Request body:

{ "token": "invite-token-from-email" }
{ "accepted": true }

Change member role

PATCH /v1/orgs/:slug/members/:userId — Auth: Bearer token (admin or owner)

{ "role": "admin" }

Remove member

DELETE /v1/orgs/:slug/members/:userId — Auth: Bearer token (admin or owner)

{ "removed": true }

Org wallet

GET /v1/orgs/:slug/wallet — Auth: Bearer token (member)

Same shape as personal wallet. Top up, configure auto top-up, and list transactions via:

  • POST /v1/orgs/:slug/wallet/top-up
  • PATCH /v1/orgs/:slug/wallet/auto-top-up
  • GET /v1/orgs/:slug/wallet/transactions

All behave identically to personal wallet endpoints.

Org spend policies

GET /v1/orgs/:slug/policies — Auth: Bearer token (member)

Returns spend policies for the org. Org policies take priority over the token holder's personal policy when purchasing on behalf of the org.

POST /v1/orgs/:slug/policies — Auth: Bearer token (admin or owner)

Same fields as personal spend policy creation. See Spend policies.

Org packages

GET /v1/orgs/:slug/packages — Auth: Bearer token (member)

Lists packages owned by the org. Supports ?type= and ?status= filters.

PATCH /v1/orgs/:slug/packages/:listingId — Auth: Bearer token (admin or owner)

Change package visibility. visibility values: "public", "private", "org_only".


Agent network — Sessions

Open session

POST /v1/network/sessions — Auth: purchase scope

Opens a session with a published service.

Request body:

{
  "vendor": "acme",
  "slug": "travel-agent",
  "intent": "book_travel",
  "context": { "destination": "Tokyo", "budgetCents": 150000 },
  "settlementMethod": "wallet"
}
FieldTypeRequiredDescription
vendorstringYesVendor slug
slugstringYesListing slug
intentstringNoSends an intent.open message
contextobjectNoArbitrary context
settlementMethodstringNostripe_mpp, stripe_acp, free, wallet

Response:

{
  "session": {
    "id": "uuid",
    "status": "open",
    "protocol": "mcp",
    "transport": "streamable_http",
    "createdAt": "2026-03-19T12:00:00.000Z"
  },
  "listingId": "uuid"
}

Get session

GET /v1/network/sessions/:id — Auth: Bearer token (buyer or vendor)

{
  "session": { "id": "uuid", "status": "open" },
  "role": "buyer",
  "listingSlug": "travel-agent",
  "vendorSlug": "acme"
}

Send message

POST /v1/network/sessions/:id/messages — Auth: purchase scope

Request body:

{
  "type": "quote.request",
  "correlationId": "optional-corr-id",
  "payload": { "budgetCents": 150000 }
}

Response:

{
  "sent": { "id": "msg-uuid", "type": "quote.request" },
  "responses": [
    { "id": "msg-uuid", "type": "quote.response", "payload": {} }
  ]
}

Get messages

GET /v1/network/sessions/:id/messages — Auth: Bearer token (buyer or vendor)

Query parameters: limit (max 200, default 50), after (message ID cursor).

{
  "messages": [
    {
      "id": "uuid",
      "direction": "outbound",
      "messageType": "intent.open",
      "deliveryStatus": "delivered",
      "createdAt": "2026-03-19T12:00:00.000Z",
      "payload": {}
    }
  ]
}

Close session

POST /v1/network/sessions/:id/close — Auth: purchase scope

{ "ok": true, "session": { "id": "uuid", "status": "closed" } }

Vendor inbox

GET /v1/network/inbox — Auth: sell scope

Returns open sessions targeting the vendor's listings.

Query parameters: limit (max 100, default 50).

{
  "sessions": [
    {
      "session": { "id": "uuid", "status": "open" },
      "listingSlug": "travel-agent"
    }
  ]
}

Service health

GET /v1/network/service-health — Auth: sell scope

Latest health probe results per listing for the vendor.

{
  "listings": [
    {
      "id": "uuid",
      "slug": "travel-agent",
      "title": "Travel Agent",
      "serviceEndpoint": "https://api.acme.com/mcp",
      "serviceStatus": "active",
      "uptimePct": "99.95",
      "latestCheck": {
        "status": "healthy",
        "responseMs": 340,
        "toolsCount": 5,
        "error": null,
        "checkedAt": "2026-03-19T12:00:00.000Z"
      }
    }
  ]
}

Agent network — Services

Discover live services

GET /v1/services

No authentication required.

Query parameters:

ParameterTypeDescription
toolstringFilter by tool name
protocolstringmcp, a2a, https, acp
settlementstringFilter by settlement method
maxPerCallCentsnumberMaximum per-call cost
statusactive | inactive | degradedService status
verifiedbooleanOnly verified vendors
sortrecent | trustedSort order (default: recent)
pagenumberPage (default: 1)
per_pagenumber1–50 (default: 20)

Response:

{
  "services": [
    {
      "id": "uuid",
      "slug": "travel-agent",
      "title": "Travel Agent",
      "vendorSlug": "acme",
      "serviceCard": {
        "protocol": "mcp",
        "transport": "streamable_http",
        "endpoint": "https://api.acme.com/mcp",
        "toolNames": ["search_flights", "book_flight"],
        "settlementMethods": ["wallet", "stripe_mpp"],
        "perCallCents": 5,
        "status": "active"
      },
      "totalCalls": 12400,
      "successRate": "99.20",
      "avgResponseMs": 340,
      "uptimePct": "99.95"
    }
  ],
  "total": 1,
  "page": 1,
  "perPage": 20
}

Call tool (metered)

POST /v1/services/:vendor/:slug/call — Auth: purchase scope

Invokes a tool on a live service. Mog deducts perCallCents from the caller's wallet.

Request body:

{
  "tool": "search_flights",
  "input": { "origin": "SFO", "destination": "NRT" },
  "maxCostCents": 10,
  "sessionId": "optional-session-uuid"
}
FieldTypeRequiredDescription
toolstringYesTool name to invoke
inputobjectNoTool input parameters
maxCostCentsnumberNoReject if cost exceeds this
sessionIdstringNoAttach to an existing session

Response:

{
  "result": { "flights": [] },
  "costCents": 5,
  "walletBalanceCents": 4495,
  "usageRecordId": "uuid",
  "durationMs": 320
}

Agent network — Vendor service registration

Update listing with service fields

PATCH /v1/vendor/listings/:id — Auth: sell scope

In addition to the standard listing fields, you can set:

FieldTypeDescription
serviceEndpointstring | nullLive service URL
serviceProtocolmcp | a2a | https | acp | nullProtocol
serviceTransportstreamable_http | sse | stdio | jsonrpc | nullTransport
pricingModelone_time | metered | monthly | annualPricing model
perCallCentsnumberPer-call cost in cents (metered pricing)
settlementMethodsstring[]stripe_mpp, stripe_acp, free, wallet, invoice
capabilitiesobject | nullMachine-readable capability descriptions
agentCardobject | nullPublic agent card metadata

On this page

Base URL
Authentication
Errors
Health
Authentication endpoints
Start device flow
Poll device flow
Approve device code
Revoke token
List API tokens
Revoke token by ID
Search
Listings
Get listing
Get releases
Reviews
Get reviews
Create or update review
Vote on review
Purchases & entitlements
Purchase a listing
List entitlements
Check entitlement
List orders
Downloads
Get download URL
User
Get current user
Update profile
Delete account
Vendor
Create or update vendor profile
Start Stripe Connect onboarding
Upload release
Publish release
Update listing
Get vendor analytics
Vendor verification
Get verification status
Start domain verification
Check domain verification
Start GitHub org verification
Signing keys
List signing keys
Register or rotate signing key
Revoke signing key
Reply to review
Spend policies
List policies
Create policy
Update policy
Delete policy
Leaderboard
Audits
Webhooks
Stripe webhook
Billing
Spending overview
List payment methods
Create setup intent
Create billing portal session
Create seller dashboard link
Seller overview
Wallet
Get wallet
Top up wallet
Configure auto top-up
Wallet transactions
Organizations
Create organization
List organizations
Get organization
Update organization
Delete organization
Invite member
Accept invitation
Change member role
Remove member
Org wallet
Org spend policies
Org packages
Agent network — Sessions
Open session
Get session
Send message
Get messages
Close session
Vendor inbox
Service health
Agent network — Services
Discover live services
Call tool (metered)
Agent network — Vendor service registration
Update listing with service fields