This endpoint has two modes:
- public read for approved listings
- private pending-status check when
?email=is supplied
Both modes include a machine-readable badge object. For approved paid listings,
badge.verification.status is paid_dofollow and is_dofollow is true. Approved free
listings and pending submissions return is_dofollow: false. On free listings,
verified describes the recorded badge or link-back verification state; it does not
verify ownership or an agent claim. Founder-only embed utilities are not returned.
Approved mode
When the slug already points to an approved listing, you get the richer detail object plus the public badge verification state.
Approved responses now include:
editorial_summaryfor concise catalog framingoverviewfor the longer product body used on the detail pagetrustfor the public-safe review source, source quality, evidence links, and review note shown on the listing pagecompatibility_matrixfor editorial stack, integration, and deployment compatibility rows on agent products when that data has been curated
Pending mode
When the listing is still pending, you must supply the original submitter email. This is an email-match check, not inbox or ownership verification. The response is intentionally minimal and exposes pending state, the original creation timestamp, claim-review metadata, and a badge state that makes it explicit that approval has not happened yet.
Rejected submissions are not exposed by this endpoint, even with a matching email.
A 404 response can therefore mean an unknown slug, an unavailable pending listing,
or a rejected submission; it does not identify the review outcome.
Owner-only embed code is not returned by this public endpoint. After approval, founders receive the personalized launch kit and badge snippet through the existing email flow.
/api/v1/products/:slugThis is the status-check endpoint for programmatic submissions and the canonical read endpoint for approved product details and public badge verification state.
Auth
No API keys. No account auth. Public JSON endpoints only.
Review model
Pending status is visible only to the original submitter email. Approved status is public.
Cache
Dynamic server response.
Example request
curl "https://www.madewithstack.com/api/v1/products/agentflow?email=founder@agentflow.dev"
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
email | string | No | Required only when checking the status of a pending submission. Must match the submitter email. |
Responses
Approved listing
Returns the richer approved product detail object plus a machine-readable public badge-status payload when the slug is already public.
{
"product": {
"id": "string",
"name": "string",
"slug": "string",
"description": "string",
"url": "string",
"favicon_url": "string | null",
"founder_name": "string | null",
"founder_twitter": "string | null",
"founder_profile_slug": "string | null",
"launch_date": "string | null",
"status": "\"approved\"",
"created_at": "string",
"approved_at": "string | null",
"view_count": "number",
"is_featured": "boolean",
"featured_rank": "number",
"screenshot_url": "string | null",
"submission_tier": "\"free\" | \"paid_fast_track\"",
"review_priority": "number",
"audience_tags": [
"\"for-developers\" | \"for-founders\" | \"b2b\" | \"consumer\""
],
"badge_verified": "boolean",
"submitted_by_agent": "boolean",
"is_agent_product": "boolean",
"qualification_type": "\"agent_native\" | \"agent_built\" | \"agentic_workflow\" | null",
"agent_use_case": "\"support\" | \"research\" | \"operations\" | \"sales\" | \"voice\" | \"browser_automation\" | null",
"qualification_statement": "string | null",
"workflow_summary": "string | null",
"agent_tools_used": "string[]",
"supporting_links": "string[]",
"claim_review_status": "\"submitted\" | \"verified\" | \"not_verified\" | \"needs_revision\" | null",
"claim_reviewed_at": "string | null",
"claim_review_notes": "string | null",
"claim_verified_by": "string | null",
"claim_evidence_summary": "string | null",
"tools": [
{
"id": "string",
"name": "string",
"slug": "string",
"description": "string | null",
"icon_url": "string | null",
"category": "string",
"product_count": "number",
"created_at": "string"
}
],
"overview": "string | null",
"editorial_summary": "string | null",
"trust": {
"review_model": "\"manual\"",
"source_kind": "\"curated\" | \"user_submission\" | \"other\"",
"source_quality": "\"curated_evidence\" | \"reviewed_with_evidence\" | \"manual_review_only\"",
"source_url": "string",
"verified_at": "string | null",
"public_note": "string | null",
"evidence": [
{
"type": "string",
"url": "string"
}
]
},
"compatibility_matrix": [
{
"tool": {
"id": "string",
"name": "string",
"slug": "string",
"description": "string | null",
"icon_url": "string | null",
"category": "string",
"product_count": "number",
"created_at": "string"
},
"status": "\"core_stack\" | \"has_integration\" | \"supports_deployment\" | \"works_with\"",
"note": "string | null"
}
]
},
"badge": {
"available": "boolean",
"image_url": "string",
"verification": {
"status": "\"pending_approval\" | \"awaiting_verification\" | \"verified\" | \"paid_dofollow\"",
"is_dofollow": "boolean (true only for paid fast-track listings)",
"requires_badge_install": "boolean",
"requires_manual_review": "boolean",
"detail": "string"
}
},
"claim_status": "verified",
"claim_eligibility": "agent_directory",
"next_action_code": "APPROVED_FOR_AGENT_DIRECTORY"
}Pending submission
Returns minimal pending-state data plus badge availability state when the slug exists in pending status and the submitter email matches.
{
"product": {
"slug": "agentflow",
"name": "AgentFlow",
"status": "pending",
"created_at": "2026-03-11T09:15:00.000Z"
},
"badge": {
"available": "boolean",
"image_url": "string",
"verification": {
"status": "\"pending_approval\" | \"awaiting_verification\" | \"verified\" | \"paid_dofollow\"",
"is_dofollow": "boolean (true only for paid fast-track listings)",
"requires_badge_install": "boolean",
"requires_manual_review": "boolean",
"detail": "string"
}
},
"claim_status": "submitted",
"claim_eligibility": "agent_directory",
"next_action_code": "UNDER_EDITORIAL_REVIEW"
}Error codes
| Code | Status | Meaning |
|---|---|---|
VALIDATION_ERROR | 400 | Missing, malformed, or unsupported request data. |
INTERNAL_ERROR | 500 | Unexpected server error. Retry later. |
Operational notes
- Call this after submitting to poll pending review status, or call it without email when reading an approved listing and its public badge state.
- Non-public listings require a matching submitter email. Rejected submissions return 404 even with a matching email; 404 does not identify the review outcome.
- Approved listings do not require the submitter email parameter.
- Approved responses include editorial_summary, overview, trust derived from the primary review source (or null when absent), and compatibility_matrix rows when editorial compatibility data exists.
- Public badge data describes recorded badge verification and link treatment, not product ownership or agent-claim verification. Owner-only embed code stays in the approval email and launch kit flow.