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:
| Scope | Required for |
|---|---|
read | Entitlements, reviews |
purchase | Purchases |
download | Download URLs |
sell | Vendor operations, uploads |
Errors
Errors return a JSON body with a message field:
{ "message": "Listing not found" }
| Status | Meaning |
|---|---|
400 | Bad request / validation error |
401 | Missing or invalid token |
402 | Payment / approval required |
403 | Insufficient token scope |
404 | Resource not found |
422 | Unprocessable entity |
429 | Rate limit exceeded |
500 | Internal 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 }
Search
GET /v1/search
Search packages. No authentication required.
Query parameters:
| Parameter | Type | Description |
|---|---|---|
q | string | Full-text search query |
type | skill | rule | bundle | template | mcp | Filter by package type |
target | cursor | claude-code | codex | gemini-cli | windsurf | generic | Filter by agent target |
sort | popular | recent | rated | price_asc | price_desc | trusted | Sort order (default: popular). trusted ranks by trust metrics. |
page | number | Page number (default: 1, ignored when cursor is set) |
per_page | number | Results per page (1–50, default: 20) |
free | boolean | Only free packages |
tool | string | Filter by MCP tool name (GIN index) |
tags | string | Comma-separated tag filter |
live | boolean | Only listings with a registered service endpoint |
protocol | mcp | a2a | https | acp | Filter by service protocol |
settlement | string | Filter by settlement method (e.g. stripe_mpp) |
verified | boolean | Only verified vendors |
cursor | string | Cursor 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:
| Field | Type | Description |
|---|---|---|
archive | file (.zip) | Package archive |
priceCents | number | Price 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:
| Parameter | Type | Description |
|---|---|---|
window | all | trending | hot | Ranking window (default: all). all sorts by mogRating; trending and hot sort by recent install velocity. |
type | skill | rule | bundle | template | Filter by package type |
limit | number | Max results (default: 50, max: 200) |
offset | number | Pagination 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:
| Parameter | Type | Description |
|---|---|---|
type | string | Filter by package type |
status | passed | flagged | failed | pending | Filter by scan status |
limit | number | Max results (default: 20, max: 100) |
offset | number | Pagination 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/..." }
Create seller dashboard link
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-upPATCH /v1/orgs/:slug/wallet/auto-top-upGET /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"
}
| Field | Type | Required | Description |
|---|---|---|---|
vendor | string | Yes | Vendor slug |
slug | string | Yes | Listing slug |
intent | string | No | Sends an intent.open message |
context | object | No | Arbitrary context |
settlementMethod | string | No | stripe_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:
| Parameter | Type | Description |
|---|---|---|
tool | string | Filter by tool name |
protocol | string | mcp, a2a, https, acp |
settlement | string | Filter by settlement method |
maxPerCallCents | number | Maximum per-call cost |
status | active | inactive | degraded | Service status |
verified | boolean | Only verified vendors |
sort | recent | trusted | Sort order (default: recent) |
page | number | Page (default: 1) |
per_page | number | 1–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"
}
| Field | Type | Required | Description |
|---|---|---|---|
tool | string | Yes | Tool name to invoke |
input | object | No | Tool input parameters |
maxCostCents | number | No | Reject if cost exceeds this |
sessionId | string | No | Attach 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:
| Field | Type | Description |
|---|---|---|
serviceEndpoint | string | null | Live service URL |
serviceProtocol | mcp | a2a | https | acp | null | Protocol |
serviceTransport | streamable_http | sse | stdio | jsonrpc | null | Transport |
pricingModel | one_time | metered | monthly | annual | Pricing model |
perCallCents | number | Per-call cost in cents (metered pricing) |
settlementMethods | string[] | stripe_mpp, stripe_acp, free, wallet, invoice |
capabilities | object | null | Machine-readable capability descriptions |
agentCard | object | null | Public agent card metadata |