{
  "openapi": "3.1.0",
  "info": {
    "title": "Wouldliker API",
    "description": "Public, read-only sound recommendation API for short-form video (TikTok, Reels, Shorts). Wouldliker describes fit and evidence, not guaranteed views.",
    "version": "1.2.0",
    "contact": {
      "name": "Wouldliker",
      "url": "https://wouldliker.com/developers/"
    },
    "license": {
      "name": "Wouldliker public data license",
      "url": "https://wouldliker.com/developers/license/"
    }
  },
  "servers": [
    {
      "url": "https://wouldliker.com/api",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "sounds",
      "description": "Named Wouldliker sound directions."
    },
    {
      "name": "proof",
      "description": "Public proof examples."
    },
    {
      "name": "momentum",
      "description": "Sound health / momentum snapshot."
    },
    {
      "name": "recommend",
      "description": "Recommendation and brief generation."
    },
    {
      "name": "meta",
      "description": "Service metadata."
    }
  ],
  "paths": {
    "/sounds": {
      "get": {
        "tags": [
          "sounds"
        ],
        "summary": "List all Wouldliker sounds",
        "operationId": "listSounds",
        "responses": {
          "200": {
            "description": "Sound list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SoundList"
                }
              }
            }
          }
        }
      }
    },
    "/sounds/{slug}": {
      "get": {
        "tags": [
          "sounds"
        ],
        "summary": "Get one sound profile",
        "operationId": "getSound",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "vlog",
                "product-reveal",
                "core",
                "presentation",
                "affirmation",
                "hala-madrid",
                "barcelona"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sound profile",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SoundProfile"
                }
              }
            }
          },
          "404": {
            "description": "Sound not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/proof": {
      "get": {
        "tags": [
          "proof"
        ],
        "summary": "List public proof examples",
        "operationId": "listProof",
        "parameters": [
          {
            "name": "sound",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Proof list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProofList"
                }
              }
            }
          }
        }
      }
    },
    "/momentum": {
      "get": {
        "tags": [
          "momentum"
        ],
        "summary": "Sound health and momentum snapshot",
        "operationId": "getMomentum",
        "responses": {
          "200": {
            "description": "Momentum snapshot",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MomentumSnapshot"
                }
              }
            }
          }
        }
      }
    },
    "/recommend": {
      "post": {
        "tags": [
          "recommend"
        ],
        "summary": "Recommend a Wouldliker sound for a described clip",
        "operationId": "recommend",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecommendRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Recommendation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SoundRecommendation"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/brief": {
      "post": {
        "tags": [
          "recommend"
        ],
        "summary": "Generate a brief and caption pack",
        "operationId": "generateBrief",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BriefRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Brief and caption pack",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BriefResponse"
                }
              }
            }
          },
          "422": {
            "description": "Invalid sound_slug or language",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "tags": [
          "meta"
        ],
        "summary": "OpenAPI 3.1 specification",
        "operationId": "getOpenapi",
        "responses": {
          "200": {
            "description": "OpenAPI document",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/health": {
      "get": {
        "tags": [
          "meta"
        ],
        "summary": "Service liveness",
        "operationId": "getHealth",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ok"
                      ]
                    },
                    "api_version": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "status",
                    "api_version"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SoundReference": {
        "type": "object",
        "required": [
          "sound_slug",
          "name",
          "tiktok_sound_url"
        ],
        "properties": {
          "sound_slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "page_url": {
            "type": "string",
            "format": "uri"
          },
          "tiktok_sound_url": {
            "type": "string",
            "format": "uri"
          },
          "why": {
            "type": "string"
          }
        }
      },
      "ProofExample": {
        "type": "object",
        "properties": {
          "creator": {
            "type": "string"
          },
          "sound_slug": {
            "type": "string"
          },
          "sound_name": {
            "type": "string"
          },
          "views": {
            "type": "integer"
          },
          "usual_range": {
            "type": "string"
          },
          "multiplier_over_usual_upper": {
            "type": "number"
          },
          "platform": {
            "type": "string",
            "enum": [
              "tiktok",
              "reels",
              "shorts"
            ]
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "snapshot_date": {
            "type": "string",
            "format": "date"
          },
          "label": {
            "type": "string"
          }
        }
      },
      "SoundProfile": {
        "type": "object",
        "required": [
          "sound_slug",
          "name",
          "saturation_state",
          "is_aigc_friendly"
        ],
        "properties": {
          "sound_slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "page_url": {
            "type": "string",
            "format": "uri"
          },
          "tiktok_sound_url": {
            "type": "string",
            "format": "uri"
          },
          "clip_job": {
            "type": "string"
          },
          "fit_note": {
            "type": "string"
          },
          "avoid_note": {
            "type": "string"
          },
          "proof": {
            "type": "object",
            "properties": {
              "strength": {
                "type": "string",
                "enum": [
                  "direct_public_proof",
                  "limited_direct_proof",
                  "rising_fit_route",
                  "fit_first_lighter_direct_proof"
                ]
              },
              "section_url": {
                "type": "string",
                "format": "uri"
              },
              "count": {
                "type": "integer"
              },
              "examples": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ProofExample"
                }
              }
            }
          },
          "saturation_state": {
            "type": "string",
            "enum": [
              "default_route",
              "rising_fit_route",
              "steady",
              "saturating",
              "cooling",
              "paused"
            ]
          },
          "is_aigc_friendly": {
            "type": "boolean"
          },
          "aigc_note": {
            "type": "string",
            "nullable": true
          },
          "primary_for_intents": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "fallback_for_intents": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "related_pages": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            }
          },
          "last_verified_at": {
            "type": "string",
            "format": "date"
          }
        }
      },
      "SoundList": {
        "type": "object",
        "required": [
          "type",
          "api_version",
          "sounds"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "sound_list"
            ]
          },
          "api_version": {
            "type": "string"
          },
          "taxonomy_version": {
            "type": "string"
          },
          "generated_at": {
            "type": "string",
            "format": "date"
          },
          "default_sound_slug": {
            "type": "string"
          },
          "sounds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SoundProfile"
            }
          },
          "copy_boundary": {
            "type": "string"
          }
        }
      },
      "ProofList": {
        "type": "object",
        "required": [
          "type",
          "api_version",
          "examples"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "proof_list"
            ]
          },
          "api_version": {
            "type": "string"
          },
          "generated_at": {
            "type": "string",
            "format": "date"
          },
          "filters": {
            "type": "object",
            "properties": {
              "sound": {
                "type": "string",
                "nullable": true
              },
              "limit": {
                "type": "integer"
              },
              "since": {
                "type": "string",
                "format": "date",
                "nullable": true
              }
            }
          },
          "examples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProofExample"
            }
          },
          "copy_boundary": {
            "type": "string"
          }
        }
      },
      "MomentumSnapshot": {
        "type": "object",
        "required": [
          "type",
          "api_version",
          "generated_at",
          "window_days",
          "leading"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "momentum_snapshot"
            ]
          },
          "api_version": {
            "type": "string"
          },
          "generated_at": {
            "type": "string",
            "format": "date"
          },
          "window_days": {
            "type": "integer"
          },
          "leading": {
            "$ref": "#/components/schemas/SoundReference"
          },
          "rising": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SoundReference"
            }
          },
          "saturating": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SoundReference"
            }
          },
          "cooling": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SoundReference"
            }
          },
          "paused": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SoundReference"
            }
          },
          "claims": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "metric": {
                  "type": "string"
                },
                "display": {
                  "type": "string"
                },
                "copy": {
                  "type": "string"
                }
              }
            }
          },
          "copy_boundary": {
            "type": "string"
          }
        }
      },
      "RecommendRequest": {
        "type": "object",
        "required": [
          "description"
        ],
        "properties": {
          "description": {
            "type": "string",
            "minLength": 3,
            "maxLength": 1000,
            "description": "Natural-language description of the clip the creator/agent is making."
          },
          "platform": {
            "type": "string",
            "enum": [
              "tiktok",
              "reels",
              "shorts"
            ],
            "nullable": true
          },
          "duration_seconds": {
            "type": "integer",
            "minimum": 1,
            "maximum": 600,
            "nullable": true
          },
          "content_type": {
            "type": "string",
            "enum": [
              "vlog",
              "product_reveal",
              "explainer",
              "beauty",
              "football"
            ],
            "nullable": true
          },
          "tone": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "is_aigc": {
            "type": "boolean",
            "default": false
          },
          "language": {
            "type": "string",
            "enum": [
              "en",
              "es"
            ],
            "default": "en"
          }
        }
      },
      "SoundRecommendation": {
        "type": "object",
        "required": [
          "type",
          "api_version",
          "matched_intent",
          "primary_sound",
          "saturation_state"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "sound_recommendation"
            ]
          },
          "api_version": {
            "type": "string"
          },
          "taxonomy_version": {
            "type": "string"
          },
          "request_echo": {
            "type": "object"
          },
          "matched_intent": {
            "type": "object",
            "properties": {
              "intent_id": {
                "type": "string"
              },
              "label": {
                "type": "string"
              },
              "confidence": {
                "type": "string",
                "enum": [
                  "high",
                  "medium",
                  "low"
                ]
              },
              "match_score": {
                "type": "number"
              },
              "matched_by": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "primary_sound": {
            "$ref": "#/components/schemas/SoundReference"
          },
          "fallback_sound": {
            "$ref": "#/components/schemas/SoundReference",
            "nullable": true
          },
          "why": {
            "type": "string"
          },
          "avoid_if": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "switch_applied": {
            "type": "object",
            "nullable": true,
            "properties": {
              "when": {
                "type": "string"
              },
              "use_sound_slug": {
                "type": "string"
              },
              "reason": {
                "type": "string"
              }
            }
          },
          "saturation_state": {
            "type": "string"
          },
          "is_aigc": {
            "type": "boolean"
          },
          "aigc_guidance": {
            "type": "object",
            "nullable": true,
            "properties": {
              "label_required": {
                "type": "boolean"
              },
              "label_text": {
                "type": "string"
              },
              "sound_specific_note": {
                "type": "string"
              }
            }
          },
          "downgrade_reason": {
            "type": "string",
            "nullable": true
          },
          "proof_examples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProofExample"
            }
          },
          "copy_boundary": {
            "type": "string"
          }
        }
      },
      "BriefRequest": {
        "type": "object",
        "required": [
          "sound_slug",
          "description"
        ],
        "properties": {
          "sound_slug": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "minLength": 3,
            "maxLength": 1000
          },
          "platform": {
            "type": "string",
            "enum": [
              "tiktok",
              "reels",
              "shorts"
            ],
            "default": "tiktok"
          },
          "duration_seconds": {
            "type": "integer",
            "nullable": true
          },
          "language": {
            "type": "string",
            "enum": [
              "en",
              "es"
            ],
            "default": "en"
          },
          "is_aigc": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "BriefResponse": {
        "type": "object",
        "required": [
          "type",
          "api_version",
          "clip_brief",
          "caption_pack"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "clip_brief"
            ]
          },
          "api_version": {
            "type": "string"
          },
          "sound": {
            "$ref": "#/components/schemas/SoundReference"
          },
          "clip_brief": {
            "type": "string"
          },
          "caption_pack": {
            "type": "object",
            "properties": {
              "short": {
                "type": "string"
              },
              "mid": {
                "type": "string"
              },
              "with_hashtags": {
                "type": "string"
              }
            }
          },
          "hashtag_pack": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "aigc_disclosure_block": {
            "type": "string",
            "nullable": true
          },
          "copy_boundary": {
            "type": "string"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error",
          "message"
        ],
        "properties": {
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "details": {
            "type": "object"
          },
          "request_id": {
            "type": "string"
          }
        }
      }
    }
  }
}