{
  "openapi": "3.1.0",
  "info": {
    "title": "Dreambit Directory API",
    "version": "1.0.0",
    "description": "Dreambit is the home of AI game dev: discover and play every AI-made game, find resources, join the creators.\n\nSubmit a game with a single https URL. Listings go live immediately and are moderated after. Agent docs: https://dreambit.app/llms.txt · MCP: https://dreambit.app/api/mcp · Skill: https://dreambit.app/skill/submit-game/SKILL.md",
    "contact": {
      "url": "https://dreambit.app/for-agents"
    }
  },
  "servers": [
    {
      "url": "https://dreambit.app"
    }
  ],
  "security": [
    {},
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/api/v1/submissions": {
      "post": {
        "operationId": "submitGame",
        "summary": "Submit a game",
        "description": "List an AI-made game. Only `url` is required; title, tagline, description and thumbnail are read from the page's OpenGraph tags when omitted. Listings go live immediately (anonymous submissions may be held for a human when the anti-spam switch is on) and are then reviewed. Add `?dry_run=1` with a session or API key to preview the enrichment without creating anything.",
        "tags": [
          "submissions"
        ],
        "parameters": [
          {
            "name": "dry_run",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "1",
                "true"
              ]
            },
            "description": "Preview enrichment without creating a listing. Requires a session or API key."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048,
                    "description": "Where the game is played. Must be https and publicly reachable; the server fetches it to verify and to read OpenGraph tags."
                  },
                  "embed_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Alternate URL to load inside the on-site player when it differs from `url` (for example an itch.io embed URL). Defaults to `url`."
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 80,
                    "description": "Game title. Filled from og:title / <title> when omitted."
                  },
                  "tagline": {
                    "type": "string",
                    "maxLength": 160,
                    "description": "One line under the title. Filled from og:description when omitted."
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000,
                    "description": "Longer description shown on the listing page."
                  },
                  "thumbnail_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Cover image, ideally 4:3. Filled from og:image when omitted. Copied into Dreambit storage."
                  },
                  "screenshots": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "maxItems": 5,
                    "description": "Up to 5 screenshots, copied into Dreambit storage."
                  },
                  "category": {
                    "type": "string",
                    "enum": [
                      "action",
                      "puzzle",
                      "rpg",
                      "platformer",
                      "strategy",
                      "simulation",
                      "racing",
                      "horror",
                      "casual",
                      "arcade",
                      "multiplayer",
                      "other"
                    ],
                    "description": "One category."
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 5,
                    "description": "Up to 5 free-form tags (slugified)."
                  },
                  "platforms": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "web",
                        "ios",
                        "android",
                        "steam",
                        "windows",
                        "mac",
                        "linux",
                        "other"
                      ]
                    },
                    "maxItems": 5,
                    "description": "Where it runs. Defaults to [\"web\"]."
                  },
                  "ai_tools": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "claude-code",
                        "claude",
                        "cursor",
                        "codex",
                        "chatgpt",
                        "copilot",
                        "gemini",
                        "grok",
                        "windsurf",
                        "bolt",
                        "v0",
                        "replit",
                        "lovable",
                        "rosebud",
                        "dreambit",
                        "other"
                      ]
                    },
                    "maxItems": 5,
                    "description": "What it was made with (\"Made with\" badges). Known values get a label; unknown tools are accepted as slugs."
                  },
                  "source_code_url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Public repo, if any."
                  },
                  "creator": {
                    "type": "object",
                    "description": "Who made it, when it is not the caller. Omit when submitting your own game with a session or API key — the listing is attributed to you automatically.",
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 80
                      },
                      "url": {
                        "type": "string",
                        "format": "uri"
                      },
                      "x_handle": {
                        "type": "string",
                        "description": "X handle without @"
                      }
                    }
                  },
                  "slug": {
                    "type": "string",
                    "description": "Requested URL slug (2–80 chars, [a-z0-9-]). Generated from the title when omitted; a suffix is added on collision."
                  },
                  "contact_email": {
                    "type": "string",
                    "description": "Reviewer contact. Never displayed."
                  },
                  "notes": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Notes for the human reviewers. Never displayed."
                  }
                }
              },
              "examples": {
                "minimal": {
                  "value": {
                    "url": "https://example.com/play"
                  }
                },
                "full": {
                  "value": {
                    "url": "https://example.com/play",
                    "title": "Neon Drift",
                    "tagline": "Slide through a synthwave city.",
                    "category": "racing",
                    "tags": [
                      "arcade",
                      "neon"
                    ],
                    "platforms": [
                      "web"
                    ],
                    "ai_tools": [
                      "claude-code"
                    ],
                    "creator": {
                      "name": "Ada",
                      "url": "https://ada.dev",
                      "x_handle": "ada"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dry-run preview (only with ?dry_run=1).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "201": {
            "description": "Listing created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmissionResult"
                }
              }
            }
          },
          "400": {
            "description": "invalid_json | invalid_field | invalid_url | url_not_allowed | slug_reserved | slug_taken",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "invalid_api_key | auth_required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "duplicate — see `existing`",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "payload_too_large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "url_unreachable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "rate_limited — honour Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "submissions_closed | not_configured",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/submissions/{id}": {
      "get": {
        "operationId": "getSubmissionStatus",
        "summary": "Poll a submission",
        "description": "Status, review verdict and rejection reason for a submission id returned by POST /submissions.",
        "tags": [
          "submissions"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubmissionStatus"
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/listings": {
      "get": {
        "operationId": "searchListings",
        "summary": "Search / browse listings",
        "description": "Live listings with filters. Query: `sort` (hot|new|top), `period` (week|month|all, for top), `category`, `platform`, `tool`, `tag`, `q`, `page`, `limit` (≤50).",
        "tags": [
          "listings"
        ],
        "parameters": [
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "hot",
                "new",
                "top"
              ],
              "default": "hot"
            }
          },
          {
            "name": "period",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "week",
                "month",
                "all"
              ],
              "default": "all"
            }
          },
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "action",
                "puzzle",
                "rpg",
                "platformer",
                "strategy",
                "simulation",
                "racing",
                "horror",
                "casual",
                "arcade",
                "multiplayer",
                "other"
              ]
            }
          },
          {
            "name": "platform",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "web",
                "ios",
                "android",
                "steam",
                "windows",
                "mac",
                "linux",
                "other"
              ]
            }
          },
          {
            "name": "tool",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tag",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 80
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 24
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of listings.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ListingCard"
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "has_more": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/listings/{slug}": {
      "get": {
        "operationId": "getListing",
        "summary": "Get one listing",
        "description": "Full public record for a live listing.",
        "tags": [
          "listings"
        ],
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The listing.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "listing": {
                      "$ref": "#/components/schemas/ListingCard"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "not_found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/resources": {
      "get": {
        "operationId": "listResources",
        "summary": "Approved resources",
        "description": "Curated tutorials, tools, showcases, prompts. Query: `category`, `page`, `limit`.",
        "tags": [
          "resources"
        ],
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "tutorial",
                "tool",
                "showcase",
                "news",
                "prompt",
                "discussion"
              ]
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 24
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Approved resources.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Resource"
                      }
                    },
                    "page": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "has_more": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Optional. API keys start with db_live_ and are created at https://dreambit.app/me/developer. A key attributes the listing to your account; an unknown/revoked key is rejected with 401 invalid_api_key."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "invalid_json",
                  "invalid_field",
                  "invalid_url",
                  "url_not_allowed",
                  "url_unreachable",
                  "slug_reserved",
                  "slug_taken",
                  "duplicate",
                  "rate_limited",
                  "submissions_closed",
                  "invalid_api_key",
                  "payload_too_large",
                  "auth_required",
                  "forbidden",
                  "not_found",
                  "not_configured",
                  "server_error"
                ]
              },
              "message": {
                "type": "string"
              },
              "field": {
                "type": "string"
              },
              "retry_after_seconds": {
                "type": "integer"
              },
              "suggestion": {
                "type": "string"
              }
            }
          },
          "existing": {
            "type": "object",
            "description": "Present on 409 duplicate.",
            "properties": {
              "slug": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "url": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      },
      "ListingCard": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "tagline": {
            "type": "string",
            "nullable": true
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Listing page on Dreambit"
          },
          "play_url": {
            "type": "string",
            "format": "uri",
            "description": "Where the game is played"
          },
          "thumbnail_url": {
            "type": "string",
            "format": "uri",
            "nullable": true
          },
          "category": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "platforms": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "ai_tools": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "upvotes": {
            "type": "integer"
          },
          "plays": {
            "type": "integer"
          },
          "embeddable": {
            "type": "boolean",
            "nullable": true
          },
          "creator": {
            "type": "object",
            "nullable": true,
            "properties": {
              "name": {
                "type": "string",
                "nullable": true
              },
              "username": {
                "type": "string",
                "nullable": true,
                "description": "Dreambit username when claimed"
              },
              "url": {
                "type": "string",
                "nullable": true
              },
              "x_handle": {
                "type": "string",
                "nullable": true
              },
              "claimed": {
                "type": "boolean"
              }
            }
          },
          "published_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "SubmissionResult": {
        "type": "object",
        "required": [
          "ok",
          "listing",
          "message"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "listing": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "slug": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "live",
                  "pending"
                ]
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "The listing page"
              },
              "status_url": {
                "type": "string",
                "format": "uri"
              },
              "embeddable": {
                "type": "boolean"
              },
              "enriched": {
                "type": "object",
                "description": "Which fields were filled from the page instead of the request.",
                "properties": {
                  "title": {
                    "type": "boolean"
                  },
                  "tagline": {
                    "type": "boolean"
                  },
                  "description": {
                    "type": "boolean"
                  },
                  "thumbnail": {
                    "type": "boolean"
                  }
                }
              },
              "attribution": {
                "type": "string",
                "enum": [
                  "anon",
                  "session",
                  "api_key"
                ]
              }
            }
          },
          "message": {
            "type": "string"
          }
        }
      },
      "SubmissionStatus": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "live",
              "pending",
              "rejected",
              "revoked"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "review": {
            "type": "object",
            "nullable": true,
            "properties": {
              "verdict": {
                "type": "string",
                "enum": [
                  "pass",
                  "flag",
                  "fail"
                ],
                "nullable": true
              },
              "summary": {
                "type": "string",
                "nullable": true
              },
              "reviewed_at": {
                "type": "string",
                "nullable": true
              }
            }
          },
          "rejection_reason": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "Resource": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string"
          },
          "category": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "excerpt": {
            "type": "string",
            "nullable": true
          },
          "commentary": {
            "type": "string",
            "nullable": true
          },
          "source_url": {
            "type": "string",
            "format": "uri"
          },
          "author_name": {
            "type": "string",
            "nullable": true
          },
          "author_handle": {
            "type": "string",
            "nullable": true
          },
          "linked_listing": {
            "type": "object",
            "nullable": true,
            "properties": {
              "slug": {
                "type": "string"
              },
              "title": {
                "type": "string"
              },
              "url": {
                "type": "string"
              }
            }
          },
          "date_published": {
            "type": "string",
            "nullable": true
          }
        }
      }
    }
  },
  "x-dreambit": {
    "llms": "https://dreambit.app/llms.txt",
    "mcp": "https://dreambit.app/api/mcp",
    "skill": "https://dreambit.app/skill/submit-game/SKILL.md",
    "feed": "https://dreambit.app/feed.json",
    "rate_limits": [
      "Anonymous: 5 submissions per hour and 20 per day per IP.",
      "API key: 30 submissions per hour per key.",
      "Signed-in session: 20 submissions per hour.",
      "Global: 300 submissions per hour across all callers.",
      "429 responses carry `Retry-After` (seconds)."
    ]
  }
}