Documentation
API Reference
Three sources of truth for any agent: REST/OpenAPI, the live A2A Agent Card, and the Skill bundle. The protocol core is Intent, Proposal, Match Session, and Match Token; PCD is the display artifact.
How to use this page
Each section is a different integration surface. Typical order:
- OpenAPI — quick-start with `GET /v1/recommend`, or move deeper into `/v1/intents`, `/v1/proposals`, `/v1/match`, and `/v1/match-tokens`. Copy-paste snippets live on Connect.
- Agent Card — point your A2A or discovery client at /.well-known/agent-card.json so capabilities stay aligned with this gateway.
- SKILL.md — for Claude / OpenClaw-style hosts, run the one-line installer on Connect; the skill maps natural language into recommend / card / showcase calls.
- Intent matching (v0.2) — merchant agents register, submit proposals, demand agents create match sessions, and accepted proposals mint match tokens. Event and object shapes are in the protocol docs below.
OpenAPI 3.0
Canonical REST contract for this gateway. The raw specification lives at /openapi.json — the same manifest consumed by ChatGPT custom GPTs and the Gemini extension.
Moras A2A Gateway
Recommend high-converting TikTok Shop products with KOC videos. Each card carries an attribution-tracking buy link that MUST be passed to the user verbatim.
Browser playground & integration guides: https://a2a.moras.ai/ — try the API live, copy ready-made snippets for OpenClaw / Cursor / Claude Code / ChatGPT / Gemini / Codex / Hermes.
recommend
Discovery endpoints — public, free, optional channel header.
GET
/v1/recommend
Recommend product cards by natural-language intent
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
intent |
query |
yes | string |
User's natural-language intent. e.g. "gift for my 3yo nephew". |
limit |
query |
no | integer |
— |
region |
query |
no | string |
ISO country code (US, UK, ...) |
channel |
query |
no | string |
Channel hint (openclaw|cursor|gemini|chatgpt|hermes|...) |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"intent": {
"type": "string"
},
"intent_id": {
"type": "string"
},
"count": {
"type": "integer"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"rec_id": {
"type": "string",
"description": "Globally unique recommendation id; primary key for attribution."
},
"product": {
"$ref": "#/components/schemas/Product"
},
"hero_pitch": {
"$ref": "#/components/schemas/HeroPitch"
},
"selection_story": {
"$ref": "#/components/schemas/SelectionStory"
},
"videos": {
"type": "array",
"items": {
"$ref": "(max depth)"
}
},
"cta": {
"$ref": "#/components/schemas/Cta"
},
"compliance": {
"type": "object",
"properties": {
"region_allow": {
"$ref": "(max depth)"
},
"risk_level": {
"$ref": "(max depth)"
}
}
},
"generated_at": {
"type": "string",
"format": "date-time"
},
"channel": {
"type": "string",
"nullable": true
}
},
"required": [
"rec_id",
"product",
"hero_pitch",
"selection_story",
"videos",
"cta",
"generated_at"
]
}
},
"proposals": {
"type": "array",
"items": {
"type": "object"
}
},
"proposal_count": {
"type": "integer"
},
"match_session_id": {
"type": "string"
},
"shopper_guide": {
"type": "string",
"description": "Warm, human-facing copy from the shopper agent (Gemini); explains how picks relate to the user's intent."
},
"note": {
"type": "string",
"description": "Optional machine hint e.g. intent_plus_trending, trending_suggested.",
"nullable": true
},
"match_tier": {
"type": "string",
"description": "raw_substring | strict | narrow | fuzzy | broadened | none — how intent rows were retrieved before trending fill."
},
"intent_source": {
"type": "string"
},
"resolved_keywords": {
"type": "array",
"items": {
"type": "string"
}
},
"resolved_categories": {
"type": "array",
"items": {
"type": "string"
}
},
"retrieval": {
"type": "object",
"properties": {
"intent_hits": {
"type": "integer"
},
"trending_fill": {
"type": "integer"
}
}
},
"generated_at": {
"type": "string",
"format": "date-time"
}
}
} |
503 | Intent engine unavailable — set GOOGLE_API_KEY or GEMINI_API_KEY on the gateway. Intent is resolved only via Gemini (no offline dictionary). Body schema — application/json {
"type": "object",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
} |
card
Hydrate or look up a previously generated PCD.
GET
/v1/cards/{recId}
Look up a previously generated PCD by recId
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
recId |
path |
yes | string |
— |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"rec_id": {
"type": "string",
"description": "Globally unique recommendation id; primary key for attribution."
},
"product": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"brand": {
"type": "string",
"nullable": true
},
"price_usd": {
"type": "number",
"nullable": true
},
"original_price_usd": {
"type": "number",
"nullable": true
},
"discount_label": {
"type": "string",
"nullable": true
},
"main_image": {
"type": "string",
"nullable": true
},
"gallery": {
"type": "array",
"items": {
"type": "string"
}
},
"category_l1": {
"type": "string",
"nullable": true
},
"category_l2": {
"type": "string",
"nullable": true
}
}
},
"hero_pitch": {
"type": "object",
"properties": {
"one_liner": {
"type": "string"
},
"why_it_wins_on_tiktok": {
"type": "string"
},
"key_benefits": {
"type": "array",
"items": {
"type": "object",
"properties": {
"icon": {
"$ref": "(max depth)"
},
"title": {
"$ref": "(max depth)"
},
"desc": {
"$ref": "(max depth)"
}
}
}
},
"target_audience": {
"type": "object",
"properties": {
"persona": {
"type": "string"
},
"age": {
"type": "string"
},
"region": {
"type": "array",
"items": {
"$ref": "(max depth)"
}
}
}
}
}
},
"selection_story": {
"type": "object",
"properties": {
"headline": {
"type": "string"
},
"bullets": {
"type": "array",
"items": {
"type": "string"
}
},
"moras_score": {
"type": "number"
}
}
},
"videos": {
"type": "array",
"items": {
"type": "object",
"properties": {
"task_id": {
"type": "string"
},
"creator": {
"type": "object",
"properties": {
"username": {
"$ref": "(max depth)"
},
"display_name": {
"$ref": "(max depth)"
},
"avatar": {
"$ref": "(max depth)"
},
"followers": {
"$ref": "(max depth)"
}
}
},
"thumbnail": {
"type": "string",
"nullable": true
},
"video_url": {
"type": "string",
"nullable": true
},
"duration_s": {
"type": "integer"
},
"gmv_usd": {
"type": "number"
},
"orders": {
"type": "integer"
},
"views": {
"type": "integer"
},
"conversion_score": {
"type": "number"
},
"tiktok_video_url": {
"type": "string",
"nullable": true
}
}
}
},
"cta": {
"type": "object",
"properties": {
"primary": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"url": {
"type": "string",
"description": "MUST be passed to user verbatim — carries attribution rec_id."
}
}
},
"secondary": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"url": {
"type": "string"
}
}
}
}
},
"compliance": {
"type": "object",
"properties": {
"region_allow": {
"type": "array",
"items": {
"type": "string"
}
},
"risk_level": {
"type": "string",
"enum": [
"low",
"medium",
"high"
]
}
}
},
"generated_at": {
"type": "string",
"format": "date-time"
},
"channel": {
"type": "string",
"nullable": true
}
},
"required": [
"rec_id",
"product",
"hero_pitch",
"selection_story",
"videos",
"cta",
"generated_at"
],
"description": "Product Card Document — the atomic recommendation unit."
} |
404 | not found |
GET
/v1/products/{productId}/card
Build a fresh PCD for a known product id
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
productId |
path |
yes | string |
— |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"rec_id": {
"type": "string",
"description": "Globally unique recommendation id; primary key for attribution."
},
"product": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"brand": {
"type": "string",
"nullable": true
},
"price_usd": {
"type": "number",
"nullable": true
},
"original_price_usd": {
"type": "number",
"nullable": true
},
"discount_label": {
"type": "string",
"nullable": true
},
"main_image": {
"type": "string",
"nullable": true
},
"gallery": {
"type": "array",
"items": {
"type": "string"
}
},
"category_l1": {
"type": "string",
"nullable": true
},
"category_l2": {
"type": "string",
"nullable": true
}
}
},
"hero_pitch": {
"type": "object",
"properties": {
"one_liner": {
"type": "string"
},
"why_it_wins_on_tiktok": {
"type": "string"
},
"key_benefits": {
"type": "array",
"items": {
"type": "object",
"properties": {
"icon": {
"$ref": "(max depth)"
},
"title": {
"$ref": "(max depth)"
},
"desc": {
"$ref": "(max depth)"
}
}
}
},
"target_audience": {
"type": "object",
"properties": {
"persona": {
"type": "string"
},
"age": {
"type": "string"
},
"region": {
"type": "array",
"items": {
"$ref": "(max depth)"
}
}
}
}
}
},
"selection_story": {
"type": "object",
"properties": {
"headline": {
"type": "string"
},
"bullets": {
"type": "array",
"items": {
"type": "string"
}
},
"moras_score": {
"type": "number"
}
}
},
"videos": {
"type": "array",
"items": {
"type": "object",
"properties": {
"task_id": {
"type": "string"
},
"creator": {
"type": "object",
"properties": {
"username": {
"$ref": "(max depth)"
},
"display_name": {
"$ref": "(max depth)"
},
"avatar": {
"$ref": "(max depth)"
},
"followers": {
"$ref": "(max depth)"
}
}
},
"thumbnail": {
"type": "string",
"nullable": true
},
"video_url": {
"type": "string",
"nullable": true
},
"duration_s": {
"type": "integer"
},
"gmv_usd": {
"type": "number"
},
"orders": {
"type": "integer"
},
"views": {
"type": "integer"
},
"conversion_score": {
"type": "number"
},
"tiktok_video_url": {
"type": "string",
"nullable": true
}
}
}
},
"cta": {
"type": "object",
"properties": {
"primary": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"url": {
"type": "string",
"description": "MUST be passed to user verbatim — carries attribution rec_id."
}
}
},
"secondary": {
"type": "object",
"properties": {
"label": {
"type": "string"
},
"url": {
"type": "string"
}
}
}
}
},
"compliance": {
"type": "object",
"properties": {
"region_allow": {
"type": "array",
"items": {
"type": "string"
}
},
"risk_level": {
"type": "string",
"enum": [
"low",
"medium",
"high"
]
}
}
},
"generated_at": {
"type": "string",
"format": "date-time"
},
"channel": {
"type": "string",
"nullable": true
}
},
"required": [
"rec_id",
"product",
"hero_pitch",
"selection_story",
"videos",
"cta",
"generated_at"
],
"description": "Product Card Document — the atomic recommendation unit."
} |
creator
Browse a creator's showcase.
GET
/v1/creators/{username}/showcase
Top products this creator has produced winning videos for
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
username |
path |
yes | string |
— |
limit |
query |
no | integer |
— |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"username": {
"type": "string"
},
"count": {
"type": "integer"
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"rec_id": {
"type": "string",
"description": "Globally unique recommendation id; primary key for attribution."
},
"product": {
"$ref": "#/components/schemas/Product"
},
"hero_pitch": {
"$ref": "#/components/schemas/HeroPitch"
},
"selection_story": {
"$ref": "#/components/schemas/SelectionStory"
},
"videos": {
"type": "array",
"items": {
"$ref": "(max depth)"
}
},
"cta": {
"$ref": "#/components/schemas/Cta"
},
"compliance": {
"type": "object",
"properties": {
"region_allow": {
"$ref": "(max depth)"
},
"risk_level": {
"$ref": "(max depth)"
}
}
},
"generated_at": {
"type": "string",
"format": "date-time"
},
"channel": {
"type": "string",
"nullable": true
}
},
"required": [
"rec_id",
"product",
"hero_pitch",
"selection_story",
"videos",
"cta",
"generated_at"
]
}
}
}
} |
intent
First-class intent objects for true A2A commerce flows.
POST
/v1/intent-mandates/sign
Sign a commerce intent mandate (RSA-SHA256 over canonical payload)
Details
Returns a signed Intent Mandate for checkout flows. Requires MORAS_PRIVATE_KEY (RSA PEM) on the gateway; returns 503 if unset.
Parameters
No parameters.
Responses
| Code | Description |
|---|---|
201 | Signed mandate Body schema — application/json {
"type": "object"
} |
400 | invalid_body |
503 | MORAS_PRIVATE_KEY not configured |
POST
/v1/intents
Create a first-class intent
Details
Parameters
No parameters.
Responses
| Code | Description |
|---|---|
201 | created Body schema — application/json · {
"type": "object",
"properties": {
"intent": {
"type": "object",
"properties": {
"intent_id": {
"type": "string"
},
"raw_query": {
"type": "string"
},
"normalized_query": {
"type": "string",
"nullable": true
},
"intent_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"target_audience": {
"type": "string",
"nullable": true
},
"budget_range": {
"type": "object",
"nullable": true
},
"region": {
"type": "string",
"nullable": true
},
"constraints": {
"type": "array",
"items": {
"type": "string"
}
},
"source_channel": {
"type": "string",
"nullable": true
},
"resolution_source": {
"type": "string",
"nullable": true
},
"resolution_summary": {
"type": "string",
"nullable": true
},
"metadata": {
"type": "object"
},
"created_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"updated_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
} |
400 | missing_fields |
GET
/v1/intents/{intentId}
Fetch an intent by id
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
intentId |
path |
yes | string |
— |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"intent": {
"type": "object",
"properties": {
"intent_id": {
"type": "string"
},
"raw_query": {
"type": "string"
},
"normalized_query": {
"type": "string",
"nullable": true
},
"intent_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"target_audience": {
"type": "string",
"nullable": true
},
"budget_range": {
"type": "object",
"nullable": true
},
"region": {
"type": "string",
"nullable": true
},
"constraints": {
"type": "array",
"items": {
"type": "string"
}
},
"source_channel": {
"type": "string",
"nullable": true
},
"resolution_source": {
"type": "string",
"nullable": true
},
"resolution_summary": {
"type": "string",
"nullable": true
},
"metadata": {
"type": "object"
},
"created_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"updated_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
} |
404 | intent_not_found |
GET
/v1/intents/{intentId}/proposals
List proposals attached to an intent
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
intentId |
path |
yes | string |
— |
include_expired |
query |
no | boolean |
— |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"intent_id": {
"type": "string"
},
"count": {
"type": "integer"
},
"proposals": {
"type": "array",
"items": {
"type": "object",
"properties": {
"proposal_id": {
"type": "string"
},
"merchant_agent_id": {
"type": "string"
},
"intent_id": {
"type": "string"
},
"product_id": {
"type": "integer"
},
"offer_title": {
"type": "string"
},
"price": {
"type": "number",
"nullable": true
},
"inventory_status": {
"type": "string"
},
"shipping_commitment": {
"type": "object"
},
"commission_plan": {
"type": "object"
},
"service_terms": {
"type": "object"
},
"evidence": {
"type": "array",
"items": {
"$ref": "(max depth)"
}
},
"valid_until": {
"type": "string",
"format": "date-time",
"nullable": true
},
"proposal_score_inputs": {
"type": "object"
},
"product_snapshot": {
"type": "object",
"nullable": true
},
"metadata": {
"type": "object"
},
"provenance": {
"type": "string"
},
"status": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"updated_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
}
} |
404 | intent_not_found |
proposal
Merchant proposals attached to an intent.
POST
/v1/proposals
Submit a merchant proposal
Details
Parameters
No parameters.
Responses
| Code | Description |
|---|---|
201 | created Body schema — application/json · {
"type": "object",
"properties": {
"proposal": {
"type": "object",
"properties": {
"proposal_id": {
"type": "string"
},
"merchant_agent_id": {
"type": "string"
},
"intent_id": {
"type": "string"
},
"product_id": {
"type": "integer"
},
"offer_title": {
"type": "string"
},
"price": {
"type": "number",
"nullable": true
},
"inventory_status": {
"type": "string"
},
"shipping_commitment": {
"type": "object"
},
"commission_plan": {
"type": "object"
},
"service_terms": {
"type": "object"
},
"evidence": {
"type": "array",
"items": {
"type": "object"
}
},
"valid_until": {
"type": "string",
"format": "date-time",
"nullable": true
},
"proposal_score_inputs": {
"type": "object"
},
"product_snapshot": {
"type": "object",
"nullable": true
},
"metadata": {
"type": "object"
},
"provenance": {
"type": "string"
},
"status": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"updated_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
} |
401 | missing registration token |
403 | invalid registration token |
404 | intent_not_found or merchant_not_found |
GET
/v1/proposals/{proposalId}
Fetch a proposal by id
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
proposalId |
path |
yes | string |
— |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"proposal": {
"type": "object",
"properties": {
"proposal_id": {
"type": "string"
},
"merchant_agent_id": {
"type": "string"
},
"intent_id": {
"type": "string"
},
"product_id": {
"type": "integer"
},
"offer_title": {
"type": "string"
},
"price": {
"type": "number",
"nullable": true
},
"inventory_status": {
"type": "string"
},
"shipping_commitment": {
"type": "object"
},
"commission_plan": {
"type": "object"
},
"service_terms": {
"type": "object"
},
"evidence": {
"type": "array",
"items": {
"type": "object"
}
},
"valid_until": {
"type": "string",
"format": "date-time",
"nullable": true
},
"proposal_score_inputs": {
"type": "object"
},
"product_snapshot": {
"type": "object",
"nullable": true
},
"metadata": {
"type": "object"
},
"provenance": {
"type": "string"
},
"status": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"updated_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
} |
404 | proposal_not_found |
match
Rank proposals into match sessions and mint match tokens.
POST
/v1/match
Create a match session from an intent and proposals
Details
Parameters
No parameters.
Responses
| Code | Description |
|---|---|
201 | created Body schema — application/json · {
"type": "object",
"properties": {
"match_session": {
"type": "object",
"properties": {
"match_session_id": {
"type": "string"
},
"intent_id": {
"type": "string"
},
"best_proposal_id": {
"type": "string",
"nullable": true
},
"ranked_proposals": {
"type": "array",
"items": {
"type": "object"
}
},
"summary": {
"type": "object"
},
"status": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"updated_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
} |
400 | missing_fields |
404 | intent_not_found or proposal_not_found |
GET
/v1/match/{matchSessionId}
Fetch a rendered match session
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
matchSessionId |
path |
yes | string |
— |
limit |
query |
no | integer |
— |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"match_session": {
"type": "object",
"properties": {
"match_session_id": {
"type": "string"
},
"intent_id": {
"type": "string"
},
"best_proposal_id": {
"type": "string",
"nullable": true
},
"ranked_proposals": {
"type": "array",
"items": {
"type": "object"
}
},
"summary": {
"type": "object"
},
"status": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"updated_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
},
"ranked_proposals": {
"type": "array",
"items": {
"type": "object"
}
},
"match_tokens": {
"type": "array",
"items": {
"type": "object",
"properties": {
"match_token_id": {
"type": "string"
},
"match_session_id": {
"type": "string"
},
"intent_id": {
"type": "string"
},
"proposal_id": {
"type": "string"
},
"acceptance_state": {
"type": "string"
},
"intent_snapshot": {
"type": "object"
},
"proposal_snapshot": {
"type": "object"
},
"ranking_snapshot": {
"type": "object"
},
"trace_ids": {
"type": "object"
},
"issued_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"expires_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"accepted_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
},
"items": {
"type": "array",
"items": {
"type": "object",
"properties": {
"rec_id": {
"type": "string",
"description": "Globally unique recommendation id; primary key for attribution."
},
"product": {
"$ref": "#/components/schemas/Product"
},
"hero_pitch": {
"$ref": "#/components/schemas/HeroPitch"
},
"selection_story": {
"$ref": "#/components/schemas/SelectionStory"
},
"videos": {
"type": "array",
"items": {
"$ref": "(max depth)"
}
},
"cta": {
"$ref": "#/components/schemas/Cta"
},
"compliance": {
"type": "object",
"properties": {
"region_allow": {
"$ref": "(max depth)"
},
"risk_level": {
"$ref": "(max depth)"
}
}
},
"generated_at": {
"type": "string",
"format": "date-time"
},
"channel": {
"type": "string",
"nullable": true
}
},
"required": [
"rec_id",
"product",
"hero_pitch",
"selection_story",
"videos",
"cta",
"generated_at"
]
}
}
}
} |
404 | match_not_found |
POST
/v1/match/{matchSessionId}/accept
Accept a ranked proposal and mint or confirm the match token
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
matchSessionId |
path |
yes | string |
— |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"match_token": {
"type": "object",
"properties": {
"match_token_id": {
"type": "string"
},
"match_session_id": {
"type": "string"
},
"intent_id": {
"type": "string"
},
"proposal_id": {
"type": "string"
},
"acceptance_state": {
"type": "string"
},
"intent_snapshot": {
"type": "object"
},
"proposal_snapshot": {
"type": "object"
},
"ranking_snapshot": {
"type": "object"
},
"trace_ids": {
"type": "object"
},
"issued_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"expires_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"accepted_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
} |
404 | match_not_found |
GET
/v1/match-tokens/{matchTokenId}
Fetch a match token by id
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
matchTokenId |
path |
yes | string |
— |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"match_token": {
"type": "object",
"properties": {
"match_token_id": {
"type": "string"
},
"match_session_id": {
"type": "string"
},
"intent_id": {
"type": "string"
},
"proposal_id": {
"type": "string"
},
"acceptance_state": {
"type": "string"
},
"intent_snapshot": {
"type": "object"
},
"proposal_snapshot": {
"type": "object"
},
"ranking_snapshot": {
"type": "object"
},
"trace_ids": {
"type": "object"
},
"issued_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"expires_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"accepted_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
} |
404 | match_token_not_found |
merchant
Merchant / supply-side Agent registry and lifecycle endpoints.
POST
/v1/merchant/register
Register a merchant Agent (intent-matching v0.1)
Details
Registers a merchant agent endpoint, subscription tags, capabilities, and routing scope for Moras A2A. Registration is persisted and token-protected; merchants can heartbeat, health-check, receive Intent.Surge dispatches, and submit proposals. See /docs/INTENT_MATCHING_PROTOCOL.md on this gateway.
Parameters
No parameters.
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"status": {
"type": "string"
},
"created": {
"type": "boolean"
},
"merchant_id": {
"type": "string"
},
"registration_token": {
"type": "string",
"description": "Secret token used for heartbeat, updates, deactivation, and proposal submission."
},
"merchant": {
"type": "object",
"properties": {
"merchant_id": {
"type": "string"
},
"agent_endpoint": {
"type": "string"
},
"subscription_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"capabilities": {
"type": "array",
"items": {
"type": "string"
}
},
"regions": {
"type": "array",
"items": {
"type": "string"
}
},
"category_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"inventory_scope": {
"type": "array",
"items": {
"type": "object"
}
},
"protocol_version": {
"type": "string",
"nullable": true
},
"a2a_capabilities": {
"type": "object"
},
"metadata": {
"type": "object"
},
"status": {
"type": "string"
},
"registered_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"last_seen_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"deactivated_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
} |
400 | missing_fields — merchant_id and agent_endpoint required |
GET
/v1/merchant/{merchantId}
Fetch a registered merchant Agent
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
merchantId |
path |
yes | string |
— |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"status": {
"type": "string",
"nullable": true
},
"merchant": {
"type": "object",
"properties": {
"merchant_id": {
"type": "string"
},
"agent_endpoint": {
"type": "string"
},
"subscription_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"capabilities": {
"type": "array",
"items": {
"type": "string"
}
},
"regions": {
"type": "array",
"items": {
"type": "string"
}
},
"category_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"inventory_scope": {
"type": "array",
"items": {
"type": "object"
}
},
"protocol_version": {
"type": "string",
"nullable": true
},
"a2a_capabilities": {
"type": "object"
},
"metadata": {
"type": "object"
},
"status": {
"type": "string"
},
"registered_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"last_seen_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"deactivated_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
} |
404 | merchant_not_found |
GET
/v1/merchant/{merchantId}/health
Probe merchant Agent health
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
merchantId |
path |
yes | string |
— |
Responses
| Code | Description |
|---|---|
200 | merchant healthy |
503 | merchant unhealthy or unreachable |
POST
/v1/merchant/heartbeat
Heartbeat a merchant Agent
Details
Parameters
No parameters.
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"status": {
"type": "string",
"nullable": true
},
"merchant": {
"type": "object",
"properties": {
"merchant_id": {
"type": "string"
},
"agent_endpoint": {
"type": "string"
},
"subscription_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"capabilities": {
"type": "array",
"items": {
"type": "string"
}
},
"regions": {
"type": "array",
"items": {
"type": "string"
}
},
"category_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"inventory_scope": {
"type": "array",
"items": {
"type": "object"
}
},
"protocol_version": {
"type": "string",
"nullable": true
},
"a2a_capabilities": {
"type": "object"
},
"metadata": {
"type": "object"
},
"status": {
"type": "string"
},
"registered_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"last_seen_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"deactivated_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
} |
401 | missing registration token |
403 | invalid registration token |
POST
/v1/merchant/{merchantId}/deactivate
Deactivate a merchant Agent
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
merchantId |
path |
yes | string |
— |
Responses
| Code | Description |
|---|---|
200 | OK Body schema — application/json · {
"type": "object",
"properties": {
"status": {
"type": "string",
"nullable": true
},
"merchant": {
"type": "object",
"properties": {
"merchant_id": {
"type": "string"
},
"agent_endpoint": {
"type": "string"
},
"subscription_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"capabilities": {
"type": "array",
"items": {
"type": "string"
}
},
"regions": {
"type": "array",
"items": {
"type": "string"
}
},
"category_tags": {
"type": "array",
"items": {
"type": "string"
}
},
"inventory_scope": {
"type": "array",
"items": {
"type": "object"
}
},
"protocol_version": {
"type": "string",
"nullable": true
},
"a2a_capabilities": {
"type": "object"
},
"metadata": {
"type": "object"
},
"status": {
"type": "string"
},
"registered_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"last_seen_at": {
"type": "string",
"format": "date-time",
"nullable": true
},
"deactivated_at": {
"type": "string",
"format": "date-time",
"nullable": true
}
}
}
}
} |
401 | missing registration token |
403 | invalid registration token |
report
Supply-side ROI reports (auth required).
GET
/v1/report/attribution
ROI report (supply side, requires X-Supply-Key)
Auth
Details
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
days |
query |
no | integer |
— |
channel |
query |
no | string |
— |
product_id |
query |
no | string |
— |
Responses
| Code | Description |
|---|---|
200 | OK |
401 | unauthorized |
Intent matching & merchant agents
Moras now exposes the core objects required for true A-to-A commerce between demand-side agents and merchant-side agents.
The merchant tag and protocol note below describe the live v0.2 registration, dispatch, proposal, and match-token contract: Intent-Matching Protocol v0.2. Merchant registry, heartbeats, health checks, proposal submission, match sessions, and match tokens are live in this gateway.
Merchant-side quick start (v0.2)
- Send `POST /v1/merchant/register` with `merchant_id`, `agent_endpoint`, and optional tags / capabilities. Store the returned `registration_token`.
- Use `X-Merchant-Token` for `POST /v1/merchant/heartbeat`, merchant updates, deactivation, and `POST /v1/proposals`.
- Consume `Intent.Surge` or poll `/v1/intents`, submit `/v1/proposals`, then let demand agents call `/v1/match` or `/v1/recommend` to rank and accept offers.
A2A Agent Card
Machine-readable A2A card (live) at /.well-known/agent-card.json. Point your agent runtime here so capabilities stay in sync.
Loading…
SKILL.md
Human-readable skill document served at /skills/moras-shop/SKILL.md — byte-for-byte what the installer copies into your agent's skills folder.