{"openapi":"3.1.0","info":{"title":"Sportsmarks API","version":"1.0.0","description":"Every Sportsmarks action. Authenticate with `Authorization: Bearer <api key>`. Errors are `{ error: { code, message, details? } }`. The same actions are MCP tools at /api/mcp."},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"}}},"security":[{"bearer":[]}],"paths":{"/api/v1/me":{"get":{"operationId":"whoami","summary":"Who am I","description":"The calling user, the org and role this call acts in, its permissions, and every org membership.","parameters":[],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/whats-next":{"get":{"operationId":"whats_next","summary":"What's next","description":"The next steps for your org right now, each with the action (tool) that does it.\n\nPermission: `org.read`.","parameters":[],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/members":{"get":{"operationId":"list_members","summary":"List members","description":"Users in the caller's org with their roles, plus open invites.\n\nPermission: `org.read`.","parameters":[],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/invites":{"post":{"operationId":"invite_member","summary":"Invite a member","description":"Invite someone to the org with a role. Emails them a one-time link (also returned as invite_url); only that email can accept it, and accepting creates their account if they don't have one. Inviting an Owner needs human confirmation.\n\nPermission: `users.manage`.\n\nMay return 202 with a confirmation preview that a human must confirm.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"role":{"type":"string","enum":["owner","licensing_director","approver","finance","viewer","submitter","athlete","representative","guardian","support","platform_admin"]}},"required":["email","role"]}}}},"responses":{"200":{"description":"OK"},"202":{"description":"Human confirmation required"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/invites/accept":{"post":{"operationId":"accept_invite","summary":"Accept an invite","description":"Join an org using an invite token. The signed-in user's email must match the invite.\n\nBrowser session only; API keys get 403.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"token":{"type":"string","minLength":10}},"required":["token"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/signups/{signup_id}/complete":{"post":{"operationId":"complete_brand_signup","summary":"Finish a brand sign-up","description":"After the person confirmed their email from the sign-up link: create the brand and make them its Owner. Only the signed-in person whose email started the sign-up can finish it, in the browser.\n\nBrowser session only; API keys get 403.","parameters":[{"name":"signup_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"signup_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["signup_id"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/members/{user_id}":{"patch":{"operationId":"update_member","summary":"Change a member's role","description":"Change a member's role. Making someone an Owner needs human confirmation.\n\nPermission: `users.manage`.\n\nMay return 202 with a confirmation preview that a human must confirm.","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"user_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"role":{"type":"string","enum":["owner","licensing_director","approver","finance","viewer","submitter","athlete","representative","guardian","support","platform_admin"]}},"required":["user_id","role"]}}}},"responses":{"200":{"description":"OK"},"202":{"description":"Human confirmation required"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}},"delete":{"operationId":"remove_member","summary":"Remove a member","description":"Remove a user from the org. Every API key and agent acting for them in this org stops working immediately.\n\nPermission: `users.manage`.","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/api-keys":{"post":{"operationId":"create_api_key","summary":"Create an API key","description":"Create a personal API key for agents and integrations, acting as you in your current org. Optional scopes narrow it to a subset of your permissions. Service keys (service: true) need users.manage and human confirmation. The key is shown once.\n\nPermission: `org.read`.\n\nMay return 202 with a confirmation preview that a human must confirm.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"scopes":{"type":"array","items":{"type":"string","enum":["org.read","reports.view","users.manage","audit.view","products.decide","licenses.decide","rulebook.edit","logos.manage","billing.request","compliance.flag","platform_agreement.sign","licenses.apply","licenses.sign","channels.connect","products.submit","sales.report","statements.pay","platform.admin"]}},"service":{"default":false,"type":"boolean"}},"required":["name"]}}}},"responses":{"200":{"description":"OK"},"202":{"description":"Human confirmation required"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}},"get":{"operationId":"list_api_keys","summary":"List API keys","description":"Your API keys and connected agents (OAuth, with oauth_client_name) in the current org, and the org's service keys if you are an Owner/Admin. Secrets are never returned.\n\nPermission: `org.read`.","parameters":[],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/api-keys/{id}":{"delete":{"operationId":"revoke_api_key","summary":"Revoke an API key","description":"Revoke one of your API keys or connected agents (or a service key, if you are an Owner/Admin). Takes effect immediately.\n\nPermission: `org.read`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/taxonomy":{"get":{"operationId":"get_taxonomy","summary":"Get the shared taxonomy","description":"The shared product classes (categories: apparel, headwear, accessories, home, toys-games, sporting-goods, paper-goods, pet, automotive, with a few subcategories like apparel/tops/t-shirt), channel types and territory groups used by every holder. Licenses and rulebooks work on these classes. Each product also gets an exact Sportsmarks category (search_product_categories) and attributes like age-group, which Sportsmarks assigns when it's submitted; holders' product_exceptions target those.","parameters":[],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/product-categories":{"get":{"operationId":"search_product_categories","summary":"Search product categories","description":"Search the Sportsmarks product categories (built from Shopify's open taxonomy v2026-08, plus licensing categories like Replica Jerseys and Pennants), e.g. \"t-shirt\", \"shot glass\", \"replica jersey\". Each result shows its product class (null = not licensable) and whether Sportsmarks added it. Use an id in a rulebook's product_exceptions. You don't need one to submit a product: Sportsmarks categorizes it.","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"maxLength":100}},{"name":"limit","in":"query","required":false,"schema":{"default":10,"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/holders":{"get":{"operationId":"search_holders","summary":"Search IP holders","description":"IP holders open to licensing, with their code (logo ID prefix), active rulebook summary and fees. Search by q (name or code); returns a page (limit, offset) with total and next_offset.","parameters":[{"name":"q","in":"query","required":false,"schema":{"description":"Text in the holder's name or code","type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}},{"name":"offset","in":"query","required":false,"schema":{"default":0,"description":"Rows to skip; pass the previous page's next_offset","type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/holders/{holder}/rulebook":{"get":{"operationId":"get_rulebook","summary":"Get a holder's rulebook","description":"A holder's active rulebook: allowed grants (category × channel × territory with approval mode), open logos, fees, required docs and banned uses.","parameters":[{"name":"holder","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/rulebook-templates":{"get":{"operationId":"list_rulebook_templates","summary":"List rulebook templates","description":"Template rulebooks a holder can start from: Small School, Governing Body, Creator Brand.","parameters":[],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/rulebook/template":{"post":{"operationId":"choose_template","summary":"Start from a template rulebook","description":"Publish a new rulebook version from a template (small_school, governing_body, creator_brand), with optional field changes. Needs human confirmation.\n\nPermission: `rulebook.edit`.\n\nMay return 202 with a confirmation preview that a human must confirm.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"template":{"type":"string"},"changes":{"type":"object","properties":{"summary":{"type":"string"},"grants_allowed":{"type":"array","items":{"type":"object","properties":{"category_path":{"type":"string"},"channel_types":{"type":"array","items":{"type":"string","enum":["shopify","amazon","wholesale"]}},"territory_groups":{"type":"array","items":{"type":"string"}},"mode":{"type":"string","enum":["auto","holder_review","blocked"]}},"required":["category_path","channel_types","territory_groups","mode"]}},"open_logo_groups":{"anyOf":[{"type":"string","const":"all"},{"type":"array","items":{"type":"string"}}]},"open_logos":{"anyOf":[{"type":"string","const":"all"},{"type":"array","items":{"type":"string"}}]},"license_approval":{"type":"string","enum":["auto","holder_review"]},"product_approval":{"type":"string","enum":["auto","holder_review"]},"blocked_coholders":{"type":"array","items":{"type":"string"}},"multi_holder_review":{"type":"boolean"},"require_verified_storefront":{"type":"boolean"},"royalty_basis":{"type":"string","const":"net_sales"},"default_royalty_rate":{"type":"number","minimum":0,"maximum":100},"co_brand_rate":{"anyOf":[{"type":"number","minimum":0,"maximum":100},{"type":"null"}]},"minimum_guarantee_cents":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"advance_cents":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"application_fee_cents":{"type":"integer","minimum":0,"maximum":9007199254740991},"annual_fee_cents":{"type":"integer","minimum":0,"maximum":9007199254740991},"required_docs":{"type":"array","items":{"type":"string","enum":["coi","code_of_conduct","w9","factory_disclosure"]}},"banned_uses":{"type":"array","items":{"type":"string"}},"banned_cobrands":{"type":"array","items":{"type":"string"}},"product_exceptions":{"type":"array","items":{"type":"object","properties":{"category_id":{"type":"string","pattern":"^[a-z]{2}(-(\\d+|sm\\d+))*$"},"label":{"type":"string","maxLength":300},"attribute":{"anyOf":[{"type":"object","properties":{"handle":{"type":"string","minLength":1,"maxLength":60},"values":{"minItems":1,"type":"array","items":{"type":"string","minLength":1,"maxLength":60}}},"required":["handle","values"]},{"type":"null"}]},"mode":{"type":"string","enum":["blocked","holder_review"]},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]}},"required":["category_id","label","mode"]}},"logo_category_rules":{"type":"array","items":{"type":"object","properties":{"logo_code":{"type":"string"},"category_path":{"type":"string"},"mode":{"type":"string","const":"blocked"}},"required":["logo_code","category_path","mode"]}},"auto_approve_confidence":{"type":"number","minimum":0,"maximum":1},"reporting_period":{"type":"string","enum":["monthly","quarterly"]},"term_months":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"escalation_contacts":{"type":"array","items":{"type":"string"}}}}},"required":["template"]}}}},"responses":{"200":{"description":"OK"},"202":{"description":"Human confirmation required"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/rulebook":{"patch":{"operationId":"update_rulebook","summary":"Update the rulebook","description":"Publish a new rulebook version by changing fields of the active one (e.g. license_approval, default_royalty_rate, grants_allowed). Rulebook versions are immutable. Needs human confirmation.\n\nPermission: `rulebook.edit`.\n\nMay return 202 with a confirmation preview that a human must confirm.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"changes":{"type":"object","properties":{"summary":{"type":"string"},"grants_allowed":{"type":"array","items":{"type":"object","properties":{"category_path":{"type":"string"},"channel_types":{"type":"array","items":{"type":"string","enum":["shopify","amazon","wholesale"]}},"territory_groups":{"type":"array","items":{"type":"string"}},"mode":{"type":"string","enum":["auto","holder_review","blocked"]}},"required":["category_path","channel_types","territory_groups","mode"]}},"open_logo_groups":{"anyOf":[{"type":"string","const":"all"},{"type":"array","items":{"type":"string"}}]},"open_logos":{"anyOf":[{"type":"string","const":"all"},{"type":"array","items":{"type":"string"}}]},"license_approval":{"type":"string","enum":["auto","holder_review"]},"product_approval":{"type":"string","enum":["auto","holder_review"]},"blocked_coholders":{"type":"array","items":{"type":"string"}},"multi_holder_review":{"type":"boolean"},"require_verified_storefront":{"type":"boolean"},"royalty_basis":{"type":"string","const":"net_sales"},"default_royalty_rate":{"type":"number","minimum":0,"maximum":100},"co_brand_rate":{"anyOf":[{"type":"number","minimum":0,"maximum":100},{"type":"null"}]},"minimum_guarantee_cents":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"advance_cents":{"anyOf":[{"type":"integer","minimum":0,"maximum":9007199254740991},{"type":"null"}]},"application_fee_cents":{"type":"integer","minimum":0,"maximum":9007199254740991},"annual_fee_cents":{"type":"integer","minimum":0,"maximum":9007199254740991},"required_docs":{"type":"array","items":{"type":"string","enum":["coi","code_of_conduct","w9","factory_disclosure"]}},"banned_uses":{"type":"array","items":{"type":"string"}},"banned_cobrands":{"type":"array","items":{"type":"string"}},"product_exceptions":{"type":"array","items":{"type":"object","properties":{"category_id":{"type":"string","pattern":"^[a-z]{2}(-(\\d+|sm\\d+))*$"},"label":{"type":"string","maxLength":300},"attribute":{"anyOf":[{"type":"object","properties":{"handle":{"type":"string","minLength":1,"maxLength":60},"values":{"minItems":1,"type":"array","items":{"type":"string","minLength":1,"maxLength":60}}},"required":["handle","values"]},{"type":"null"}]},"mode":{"type":"string","enum":["blocked","holder_review"]},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}]}},"required":["category_id","label","mode"]}},"logo_category_rules":{"type":"array","items":{"type":"object","properties":{"logo_code":{"type":"string"},"category_path":{"type":"string"},"mode":{"type":"string","const":"blocked"}},"required":["logo_code","category_path","mode"]}},"auto_approve_confidence":{"type":"number","minimum":0,"maximum":1},"reporting_period":{"type":"string","enum":["monthly","quarterly"]},"term_months":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"escalation_contacts":{"type":"array","items":{"type":"string"}}}}},"required":["changes"]}}}},"responses":{"200":{"description":"OK"},"202":{"description":"Human confirmation required"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/logos":{"get":{"operationId":"list_logos","summary":"List logos","description":"Logos with ID (e.g. BYU-002), name, rate, groups, a PNG preview_url, whether you may download the artwork, and variants (the same logo in other colorways, IDs like BYU-002.v1). With no filters, each holder's primary logo (one per institution). Filter by holder code, q (name or ID text), logo group code, license (a License ID you're party to), or licensed_to_me (brands: logos covered by your Licenses in force) to search all logos; primary=true|false overrides either way. Returns a page (limit, offset) with total and next_offset. full adds download links, colors, usage notes and variant links; for artwork use download_logo.\n\nPermission: `org.read`.","parameters":[{"name":"holder","in":"query","required":false,"schema":{"description":"Holder code, e.g. FSU (see search_holders)","type":"string"}},{"name":"q","in":"query","required":false,"schema":{"description":"Text in the logo's name or ID","type":"string"}},{"name":"group","in":"query","required":false,"schema":{"type":"string"}},{"name":"license","in":"query","required":false,"schema":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"licensed_to_me","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}},{"name":"include_retired","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}},{"name":"primary","in":"query","required":false,"schema":{"description":"Only primary logos (default when no other filter is given), or only the rest","anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}},{"name":"full","in":"query","required":false,"schema":{"description":"Include download links, colors, usage notes and variant links","anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}},{"name":"offset","in":"query","required":false,"schema":{"default":0,"description":"Rows to skip; pass the previous page's next_offset","type":"integer","minimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}},"post":{"operationId":"create_logo","summary":"Upload a logo","description":"Upload one logo (PNG + SVG both required, base64-encoded) with a name and its own royalty rate (%). Returns the next permanent ID, e.g. BYU-003. Optionally add it to existing groups.\n\nPermission: `logos.manage`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":120},"rate":{"type":"number","minimum":0,"maximum":100},"png_base64":{"type":"string","minLength":1},"svg_base64":{"type":"string","minLength":1},"colors":{"default":[],"type":"array","items":{"type":"string"}},"usage_notes":{"type":"string","maxLength":2000},"group_ids":{"default":[],"type":"array","items":{"type":"string"}}},"required":["name","rate","png_base64","svg_base64"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/logos/{code}":{"get":{"operationId":"get_logo","summary":"Get a logo","description":"One logo by its permanent ID, e.g. BYU-002, with its variants.\n\nPermission: `org.read`.","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}},"patch":{"operationId":"update_logo","summary":"Update a logo","description":"Change a logo's name, rate, files, colors, notes, or the groups it's in (group_ids replaces its membership; adding it to a group extends every License granting that group). primary: true makes it your primary logo, the one that stands for you in the catalog; the previous primary steps down. The ID never changes. Rate changes need human confirmation.\n\nPermission: `logos.manage`.\n\nMay return 202 with a confirmation preview that a human must confirm.","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"rate":{"type":"number","minimum":0,"maximum":100},"png_base64":{"type":"string"},"svg_base64":{"type":"string"},"colors":{"type":"array","items":{"type":"string"}},"usage_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}]},"group_ids":{"type":"array","items":{"type":"string"}},"primary":{"description":"Make this your primary logo","type":"boolean","const":true}},"required":["code"]}}}},"responses":{"200":{"description":"OK"},"202":{"description":"Human confirmation required"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/logos/{code}/download":{"get":{"operationId":"download_logo","summary":"Download a logo file","description":"The original PNG or SVG of a logo, or of one of its variants (variant: 2 for BYU-002.v2), for putting on product. Returns a url that downloads the file with no credentials for 10 minutes; inline=true adds the file as base64 instead (large for PNGs). Holders get their own logos; brands get logos a License in force covers, with all their variants. Every download is recorded in your audit log.\n\nPermission: `org.read`.","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","required":false,"schema":{"default":"svg","type":"string","enum":["png","svg"]}},{"name":"variant","in":"query","required":false,"schema":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},{"name":"inline","in":"query","required":false,"schema":{"description":"Also return the file itself, base64-encoded","anyOf":[{"type":"boolean"},{"type":"string","enum":["true","false"]}]}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/logo-groups":{"get":{"operationId":"list_logo_groups","summary":"List logo groups","description":"Logo groups (e.g. BYU-VINTAGE) with rate and member logo IDs. Filter by holder code; holders see their own by default.\n\nPermission: `org.read`.","parameters":[{"name":"holder","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}},"post":{"operationId":"create_logo_group","summary":"Create a logo group","description":"Create a logo group with its own royalty rate, e.g. code VINTAGE → BYU-VINTAGE at 18%. A logo can be in several groups.\n\nPermission: `logos.manage`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string","pattern":"^[A-Za-z0-9-]{2,40}$"},"name":{"type":"string","minLength":1,"maxLength":120},"rate":{"type":"number","minimum":0,"maximum":100},"logo_ids":{"default":[],"type":"array","items":{"type":"string"}}},"required":["code","name","rate"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/logos/{code}/retire":{"post":{"operationId":"retire_logo","summary":"Retire a logo","description":"Retire a logo. It keeps its ID forever so past sales still resolve, but can't be newly granted.\n\nPermission: `logos.manage`.","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string"}},"required":["code"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/logos/{code}/variants":{"post":{"operationId":"add_logo_variant","summary":"Add a logo variant","description":"Add the logo in another colorway (e.g. 'White' for a navy Block Y), as a PNG, an SVG, or both (base64). Variants are optional reference art for licensees: any License that grants the logo covers them, and they aren't approved on their own (product submission approves how they're used). Returns the variant ID, e.g. BYU-004.v2.\n\nPermission: `logos.manage`.","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"png_base64":{"type":"string"},"svg_base64":{"type":"string"}},"required":["code","name"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/logos/{code}/variants/{variant}":{"delete":{"operationId":"remove_logo_variant","summary":"Remove a logo variant","description":"Remove one variant of a logo (variant: 2 for BYU-004.v2). Its number is never reused.\n\nPermission: `logos.manage`.","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}},{"name":"variant","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/logo-groups/{code}":{"patch":{"operationId":"update_logo_group","summary":"Update a logo group","description":"Rename, re-rate, freeze, or add/remove logo IDs. Adding a logo extends every License that grants this group unless the group is frozen. Rate changes need human confirmation.\n\nPermission: `logos.manage`.\n\nMay return 202 with a confirmation preview that a human must confirm.","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"code":{"type":"string"},"name":{"type":"string","minLength":1,"maxLength":120},"rate":{"type":"number","minimum":0,"maximum":100},"frozen":{"type":"boolean"},"add_logo_ids":{"default":[],"type":"array","items":{"type":"string"}},"remove_logo_ids":{"default":[],"type":"array","items":{"type":"string"}}},"required":["code"]}}}},"responses":{"200":{"description":"OK"},"202":{"description":"Human confirmation required"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/applications":{"post":{"operationId":"create_application","summary":"Apply for a License","description":"Apply to a holder for a License: logo groups and/or logo IDs, channel types and territory groups. No categories needed: the License covers every product class the holder's rulebook allows, and Sportsmarks checks each product's category against the rulebook when it's submitted (pass categories only to ask for a narrower License). The holder's rulebook decides immediately: auto-approved (License issued, awaiting your signature), auto-denied with the failing rule IDs, or sent to the holder for review.\n\nPermission: `licenses.apply`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"holder":{"type":"string","description":"Holder code, e.g. BYU"},"logo_group_ids":{"minItems":0,"type":"array","items":{"type":"string"}},"logo_ids":{"minItems":0,"type":"array","items":{"type":"string"}},"categories":{"description":"Optional: narrow the License to these product classes (paths, covering subcategories)","minItems":0,"type":"array","items":{"type":"string"}},"channel_types":{"minItems":1,"type":"array","items":{"type":"string","enum":["shopify","amazon","wholesale"]}},"territories":{"minItems":1,"type":"array","items":{"type":"string"}}},"required":["holder","channel_types","territories"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}},"get":{"operationId":"list_applications","summary":"List applications","description":"Holders: applications to you (filter status=holder_review for your review queue). Brands: your applications.\n\nPermission: `org.read`.","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["draft","auto_approved","auto_denied","holder_review","approved","denied","withdrawn"]}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/applications/{id}":{"get":{"operationId":"get_application","summary":"Get an application","description":"One application with its rule checks and resulting License, if any.\n\nPermission: `org.read`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/applications/{id}/decide":{"post":{"operationId":"decide_application","summary":"Approve or deny an application","description":"Holder's manual decision on an application in holder_review. Approving issues the License. Needs human confirmation.\n\nPermission: `licenses.decide`.\n\nMay return 202 with a confirmation preview that a human must confirm.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"decision":{"type":"string","enum":["approve","deny"]},"note":{"type":"string","maxLength":2000}},"required":["id","decision"]}}}},"responses":{"200":{"description":"OK"},"202":{"description":"Human confirmation required"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/licenses":{"get":{"operationId":"list_licenses","summary":"List Licenses","description":"Holders: Licenses granted to brands. Brands: Licenses you hold.\n\nPermission: `org.read`.","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending_signature","active","suspended","expired","terminated"]}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/licenses/{id}":{"get":{"operationId":"get_license","summary":"Get a License","description":"One License with its logo access, scope, term, rate overrides and a short-lived agreement PDF link.\n\nPermission: `org.read`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/licenses/{id}/sign":{"post":{"operationId":"sign_license","summary":"Sign a License agreement","description":"Sign a License awaiting signature. Always returns a preview and confirm link: a brand Owner must confirm in the browser. Sportsmarks then countersigns as the holder's agent and the License becomes active.\n\nPermission: `licenses.sign`.\n\nMay return 202 with a confirmation preview that a human must confirm.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["id"]}}}},"responses":{"200":{"description":"OK"},"202":{"description":"Human confirmation required"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/quote-rate":{"post":{"operationId":"quote_rate","summary":"Quote royalty rates for a product","description":"Given the logo IDs on a product (may span holders, e.g. UTAH-004 + BYU-002), return each holder's rate and its source under your Licenses, the total stacked rate, and any holders you still need a License from.\n\nPermission: `org.read`.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"logo_ids":{"minItems":1,"type":"array","items":{"type":"string"}},"net_cents":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["logo_ids"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/audit-log":{"get":{"operationId":"export_audit_log","summary":"Export the audit log","description":"Audit entries for your org, newest first: who (user or system), role, channel (ui/rest/mcp), API key, action, target and before/after.\n\nPermission: `audit.view`.","parameters":[{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}},{"name":"before_id","in":"query","required":false,"schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},{"name":"action","in":"query","required":false,"schema":{"type":"string"}},{"name":"target_id","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/storefronts":{"post":{"operationId":"add_storefront","summary":"Add a storefront","description":"Declare a Shopify or Amazon storefront URL where you sell (e.g. ooopit.com or an Amazon brand store). Returns how to prove ownership: a DNS TXT record or a meta tag.\n\nPermission: `channels.connect`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"channel_type":{"type":"string","enum":["shopify","amazon"]},"url":{"type":"string","minLength":3}},"required":["channel_type","url"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}},"get":{"operationId":"list_storefronts","summary":"List storefronts","description":"Your declared storefronts with their ownership status and verification instructions.\n\nPermission: `org.read`.","parameters":[],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/storefronts/{id}/verify":{"post":{"operationId":"verify_storefront","summary":"Verify storefront ownership","description":"Check the storefront's DNS TXT record or home-page meta tag and mark it verified.\n\nPermission: `channels.connect`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["id"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/wholesale-accounts":{"post":{"operationId":"add_wholesale_account","summary":"Add a wholesale account","description":"Declare a wholesale buyer (campus store, boutique, distributor…). Buyer details are optional unless a holder's rulebook asks for them.\n\nPermission: `channels.connect`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"buyer_name":{"type":"string","maxLength":200},"buyer_type":{"type":"string","maxLength":80},"location":{"type":"string","maxLength":200}}}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}},"get":{"operationId":"list_wholesale_accounts","summary":"List wholesale accounts","description":"Your declared wholesale buyers.\n\nPermission: `org.read`.","parameters":[],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/store-products":{"get":{"operationId":"list_store_products","summary":"List products in your store","description":"Products in your Shopify store (read from its public product feed) with every variant's SKU, images and a suggested category, and whether each is already submitted. Pick one and pass it to submit_product_mockup as from_store so its title, variants, SKUs and images fill in automatically. Agents with a Shopify connector can instead pass variants and images directly.\n\nPermission: `org.read`.","parameters":[{"name":"storefront_id","in":"query","required":false,"schema":{"description":"Defaults to every Shopify storefront you've added","type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},{"name":"q","in":"query","required":false,"schema":{"description":"Filter by title, product type, tag or SKU","type":"string","maxLength":100}},{"name":"status","in":"query","required":false,"schema":{"default":"all","type":"string","enum":["all","not_submitted","submitted"]}},{"name":"limit","in":"query","required":false,"schema":{"default":100,"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/products":{"post":{"operationId":"submit_product_mockup","summary":"Submit a product (mockup)","description":"Submit a product once with every logo ID on it (may span holders, e.g. UTAH-001 + BYU-002), its channels, the storefronts it will be listed on, and one SKU per variant. Either pass from_store (a product from list_store_products: its title, variants, SKUs and images fill in from your store) or pass images (base64 mockups) and variants yourself. Each SKU can belong to only one product. Sportsmarks checks the images, assigns the product its category from the title, product type, tags, description and images (pass category_hint only if those don't say what it is), creates one claim per holder and evaluates each against that holder's rulebook. Missing Licenses are drafted as bundled applications.\n\nPermission: `products.submit`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"from_store":{"type":"object","properties":{"storefront_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"external_id":{"type":"string","minLength":1,"maxLength":200,"description":"Product ID (or handle) from list_store_products"}},"required":["storefront_id","external_id"]},"title":{"description":"Required unless from_store","type":"string","minLength":1,"maxLength":200},"category_hint":{"description":"Optional. What it is in a few words (\"replica football jersey\"), or its Shopify category ID (product.category.id). Sportsmarks assigns the category either way.","type":"string","maxLength":200},"product_type":{"description":"The store's product type, e.g. T-Shirt","type":"string","maxLength":120},"description":{"type":"string","maxLength":5000},"tags":{"minItems":0,"type":"array","items":{"type":"string","maxLength":80}},"attributes":{"description":"Attribute values you know, e.g. {\"age-group\": \"kids\"} from Shopify metafields","type":"object","propertyNames":{"type":"string","maxLength":60},"additionalProperties":{"type":"string","maxLength":60}},"logo_ids":{"minItems":1,"type":"array","items":{"type":"string"}},"images":{"description":"Mockups; required unless from_store, which uses the store's product images","maxItems":8,"type":"array","items":{"type":"object","properties":{"base64":{"type":"string","minLength":1},"content_type":{"default":"image/png","type":"string","enum":["image/png","image/jpeg","image/webp"]}},"required":["base64"]}},"variants":{"description":"One per variant; required unless from_store","maxItems":250,"type":"array","items":{"type":"object","properties":{"sku":{"type":"string","minLength":1,"maxLength":100},"title":{"description":"e.g. Small / Navy","anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"external_id":{"description":"The channel's variant ID, if any","anyOf":[{"type":"string","maxLength":100},{"type":"null"}]}},"required":["sku"]}},"skus":{"description":"Shorthand for variants with SKUs only","minItems":0,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"channel_types":{"description":"Defaults to shopify with from_store","minItems":1,"type":"array","items":{"type":"string","enum":["shopify","amazon","wholesale"]}},"storefront_ids":{"minItems":0,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"wholesale_account_ids":{"minItems":0,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}},"required":["logo_ids"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}},"get":{"operationId":"list_products","summary":"List products","description":"Brands: your products with their overall status. Filter by status (awaiting_license, pending, approved, denied, blocked).\n\nPermission: `org.read`.","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["awaiting_license","pending","approved","denied","blocked"]}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/products/{id}":{"patch":{"operationId":"update_product","summary":"Update and resubmit a product","description":"Change a product's declared logo IDs, images, title or description (product_type, tags, category_hint: Sportsmarks re-categorizes it), channels, storefronts or variants and resubmit it. Use it to add an undeclared logo, drop a holder's marks, or fix what a holder flagged. To add a new size or color, pass add_variants: approvals stay as they are. Claims already approved for an unchanged set of logos and unchanged images stay approved.\n\nPermission: `products.submit`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"title":{"type":"string","minLength":1,"maxLength":200},"category_hint":{"description":"Optional. What it is in a few words (\"replica football jersey\"), or its Shopify category ID (product.category.id). Sportsmarks assigns the category either way.","type":"string","maxLength":200},"product_type":{"description":"The store's product type, e.g. T-Shirt","type":"string","maxLength":120},"description":{"type":"string","maxLength":5000},"tags":{"minItems":0,"type":"array","items":{"type":"string","maxLength":80}},"attributes":{"description":"Attribute values you know, e.g. {\"age-group\": \"kids\"} from Shopify metafields","type":"object","propertyNames":{"type":"string","maxLength":60},"additionalProperties":{"type":"string","maxLength":60}},"logo_ids":{"minItems":1,"type":"array","items":{"type":"string"}},"images":{"minItems":1,"maxItems":8,"type":"array","items":{"type":"object","properties":{"base64":{"type":"string","minLength":1},"content_type":{"default":"image/png","type":"string","enum":["image/png","image/jpeg","image/webp"]}},"required":["base64"]}},"channel_types":{"minItems":1,"type":"array","items":{"type":"string","enum":["shopify","amazon","wholesale"]}},"storefront_ids":{"minItems":0,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"wholesale_account_ids":{"minItems":0,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"variants":{"description":"Replaces every variant","maxItems":250,"type":"array","items":{"type":"object","properties":{"sku":{"type":"string","minLength":1,"maxLength":100},"title":{"description":"e.g. Small / Navy","anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"external_id":{"description":"The channel's variant ID, if any","anyOf":[{"type":"string","maxLength":100},{"type":"null"}]}},"required":["sku"]}},"add_variants":{"description":"Adds variants (e.g. a new size) to the ones already there","maxItems":250,"type":"array","items":{"type":"object","properties":{"sku":{"type":"string","minLength":1,"maxLength":100},"title":{"description":"e.g. Small / Navy","anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"external_id":{"description":"The channel's variant ID, if any","anyOf":[{"type":"string","maxLength":100},{"type":"null"}]}},"required":["sku"]}},"skus":{"description":"Shorthand: replaces the variants with these SKUs, keeping titles of SKUs already there","minItems":0,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}}},"required":["id"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}},"get":{"operationId":"get_product_status","summary":"Get a product and its claims","description":"A product with its per-holder claim status. Brands see every claim, rate and holder note. A holder sees the product, the names of co-holders and the overall status, plus only its own claim.\n\nPermission: `org.read`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/products/{product_id}/bundled-applications/confirm":{"post":{"operationId":"confirm_bundled_applications","summary":"Submit the bundled License applications","description":"Submit, in one step, the License applications Sportsmarks drafted for every holder on this product you aren't licensed with yet. Each holder's rulebook decides immediately; approved Licenses then need a brand Owner's signature (sign_license).\n\nPermission: `licenses.apply`.","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"product_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["product_id"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/reviews":{"get":{"operationId":"list_reviews","summary":"List product reviews","description":"Your product claims: the products carrying your marks that your rulebook sent to you (status=holder_review, the default) or any other status. Shows co-holder names, never their terms.\n\nPermission: `reports.view`.","parameters":[{"name":"status","in":"query","required":false,"schema":{"default":"holder_review","type":"string","enum":["holder_review","approved","denied","blocked","awaiting_license"]}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/reviews/{product_id}/decide":{"post":{"operationId":"decide_review","summary":"Approve or deny a product","description":"Your decision on a product claim in holder_review. Approving freezes the rate on an Approval tied to the product's SKUs; denying blocks the product and tells the brand why. Returns a preview and confirm_token first; the same agent may confirm it with confirm_action.\n\nPermission: `products.decide`.\n\nMay return 202 with a confirmation preview that a human must confirm.","parameters":[{"name":"product_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"product_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"decision":{"type":"string","enum":["approve","deny"]},"note":{"type":"string","maxLength":2000}},"required":["product_id","decision"]}}}},"responses":{"200":{"description":"OK"},"202":{"description":"Human confirmation required"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/sales/guide":{"get":{"operationId":"get_sales_reporting_guide","summary":"How to report sales","description":"Step-by-step instructions for an agent to report a month of sales: the exact Shopify GraphQL query to run with your own Shopify connector, the formats report_sales and upload_sales_csv accept, and how the period gets attested. Call this first.\n\nPermission: `org.read`.","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/sales":{"post":{"operationId":"report_sales","summary":"Report sales","description":"Send sales lines for any period: format=shopify_orders with raw order nodes from your Shopify connector (GraphQL or REST shape), or format=lines with Sportsmarks lines (wholesale, Amazon, anything else). Each line is matched to an approved SKU and gets one royalty line per holder at the frozen rate; a sale outside a holder's Approval or License is charged at that holder's maximum royalty rate and flagged. Duplicates are ignored. Call get_sales_reporting_guide for the exact query.\n\nPermission: `sales.report`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"format":{"type":"string","enum":["shopify_orders","lines"]},"orders":{"maxItems":250,"type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"lines":{"maxItems":2000,"type":"array","items":{"type":"object","properties":{"channel_type":{"type":"string","enum":["shopify","amazon","wholesale"]},"order_id":{"type":"string","minLength":1,"maxLength":100},"kind":{"default":"sale","type":"string","enum":["sale","refund"]},"refund_id":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}]},"sku":{"type":"string","minLength":1,"maxLength":100},"quantity":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991},"net_amount":{"type":"number","minimum":0},"currency":{"default":"USD","type":"string","minLength":3,"maxLength":3},"country":{"type":"string","minLength":2,"maxLength":2},"date":{"type":"string","minLength":10},"storefront":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}]},"wholesale_account_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"retailer":{"description":"Where the customer bought it; required for wholesale","anyOf":[{"type":"string","maxLength":200},{"type":"null"}]},"buyer":{"description":"Deprecated: use retailer","anyOf":[{"type":"string","maxLength":200},{"type":"null"}]}},"required":["channel_type","order_id","sku","quantity","net_amount","country","date"]}},"storefront_id":{"description":"Storefront ID or domain these orders came from","type":"string","maxLength":300},"source_note":{"description":"e.g. 'Shopify connector in Claude'","type":"string","maxLength":200}},"required":["format"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/sales/upload":{"post":{"operationId":"upload_sales_csv","summary":"Upload a sales file","description":"Upload sales as CSV/TSV text: Shopify's order export, Amazon's All Orders report, or the Sportsmarks template (see get_sales_reporting_guide). The format is detected from the header. Same matching, royalty lines and dedupe as report_sales.\n\nPermission: `sales.report`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"csv":{"type":"string","minLength":1,"maxLength":10000000},"format":{"type":"string","enum":["sportsmarks_csv","shopify_orders_csv","amazon_orders_tsv"]},"storefront_id":{"type":"string","maxLength":300},"source_note":{"type":"string","maxLength":200}},"required":["csv"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/sales/reports":{"get":{"operationId":"list_sales_reports","summary":"List sales reports","description":"Your monthly sales reports (draft or submitted) with totals.\n\nPermission: `reports.view`.","parameters":[{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/sales/reports/{period}":{"get":{"operationId":"get_sales_report","summary":"Get a sales report","description":"One period's sales: totals, royalties per holder, exceptions by rule, how the lines arrived, how many our storefront crawl corroborates, and approved listings that are live with no reported sales.\n\nPermission: `reports.view`.","parameters":[{"name":"period","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/sales/reports/{period}/lines":{"get":{"operationId":"list_sales","summary":"List sales lines","description":"Sales lines in a period with their retailer and royalty lines; filter to exceptions (status=exception, with the rule that failed) or lines of SKUs declared not licensed (status=excluded).\n\nPermission: `reports.view`.","parameters":[{"name":"period","in":"path","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["accepted","exception","excluded"]}},{"name":"limit","in":"query","required":false,"schema":{"default":100,"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/sales/reports/{period}/submit":{"post":{"operationId":"submit_sales_report","summary":"Submit a sales report","description":"Attest that a month's sales are complete and accurate and lock the period. Returns a preview with totals per holder; a brand Owner or Finance user confirms it in the browser (agents can't). A month with no sales can be submitted as $0.\n\nPermission: `sales.report`.\n\nMay return 202 with a confirmation preview that a human must confirm.","parameters":[{"name":"period","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"period":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"}},"required":["period"]}}}},"responses":{"200":{"description":"OK"},"202":{"description":"Human confirmation required"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/sales/excluded-skus":{"post":{"operationId":"exclude_skus","summary":"Declare SKUs not licensed merchandise","description":"Declare that SKUs you sold carry no licensed marks (e.g. a plain wallet), so their sales are left out of royalties without an unknown-SKU exception. Stays declared for later months, is shown in each month's attestation, and is audited. A SKU already on one of your products can't be excluded; adding an excluded SKU to a product later undoes it.\n\nPermission: `sales.report`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"skus":{"minItems":1,"type":"array","items":{"type":"string","minLength":1,"maxLength":100}},"reason":{"type":"string","minLength":3,"maxLength":500,"description":"e.g. Plain wallets, no logos"}},"required":["skus","reason"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/royalties":{"get":{"operationId":"get_royalty_summary","summary":"Royalty summary","description":"Royalties by period. Brands: per holder, including draft periods. Holders: per licensee, from submitted reports only, and only your own royalty lines.\n\nPermission: `reports.view`.","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{4}-(0[1-9]|1[0-2])$"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/listings":{"post":{"operationId":"import_listings","summary":"Import listings","description":"Tell Sportsmarks what you have listed for sale (e.g. products from your Shopify connector, Amazon ASINs, wholesale styles): channel, the channel's product ID, title, URL and SKUs. Only listings whose SKUs are on one of your products are kept (the rest are counted as ignored). One that's live before every holder approved, or has variant SKUs not on the product, raises a flag.\n\nPermission: `products.submit`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"listings":{"minItems":1,"maxItems":500,"type":"array","items":{"type":"object","properties":{"channel_type":{"type":"string","enum":["shopify","amazon","wholesale"]},"storefront_id":{"anyOf":[{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},{"type":"null"}]},"external_id":{"type":"string","minLength":1,"maxLength":200},"title":{"type":"string","minLength":1,"maxLength":300},"url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"image_url":{"anyOf":[{"type":"string","format":"uri"},{"type":"null"}]},"skus":{"minItems":0,"type":"array","items":{"type":"string","maxLength":100}}},"required":["channel_type","external_id","title"]}}},"required":["listings"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}},"get":{"operationId":"list_listings","summary":"List listings","description":"Your listings of submitted products and their status: approved, not_approved (live before every holder approved) or dismissed. unmatched lists ones that no longer match a product's SKUs (not tracked).\n\nPermission: `org.read`.","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["approved","not_approved","unmatched","dismissed"]}},{"name":"limit","in":"query","required":false,"schema":{"default":200,"type":"integer","minimum":1,"maximum":500}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/storefronts/{storefront_id}/crawl":{"post":{"operationId":"crawl_storefront","summary":"Read a storefront's listings","description":"Read a Shopify storefront's public product feed (no credentials) and keep the products whose SKUs are on one of your products as listings; everything else is ignored. Listings live before every holder approved, or with variant SKUs not on the product, raise flags; sales of SKUs seen live are marked corroborated. Runs nightly too.\n\nPermission: `products.submit`.","parameters":[{"name":"storefront_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"storefront_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["storefront_id"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/listings/{id}/dismiss":{"post":{"operationId":"dismiss_listing","summary":"Dismiss a listing","description":"Mark a live listing as carrying no licensed marks (e.g. a blank tee), with a reason. Closes its flags; the reason is kept and audited.\n\nPermission: `products.submit`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"reason":{"type":"string","minLength":3,"maxLength":500}},"required":["id","reason"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/flags":{"get":{"operationId":"list_flags","summary":"List compliance flags","description":"Compliance flags: listings live before every holder approved, listings with variant SKUs not on the product, and sales that fail the sales gate. Brands see all of theirs; a holder sees only flags involving its own marks.\n\nPermission: `reports.view`.","parameters":[{"name":"status","in":"query","required":false,"schema":{"default":"open","type":"string","enum":["open","resolved","dismissed"]}},{"name":"limit","in":"query","required":false,"schema":{"default":50,"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/admin/orgs":{"get":{"operationId":"list_orgs","summary":"List orgs (Sportsmarks admin)","description":"Every holder and brand on Sportsmarks with its members, open invites and whether a rulebook is active.\n\nPermission: `platform.admin`.","parameters":[{"name":"type","in":"query","required":false,"schema":{"type":"string","enum":["holder","athlete","brand"]}},{"name":"q","in":"query","required":false,"schema":{"type":"string","maxLength":100}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/admin/holders":{"post":{"operationId":"create_holder_org","summary":"Create an IP holder (Sportsmarks admin)","description":"Create a school, governing body or creator (holder) or an athlete as an IP holder. The code is the permanent logo-ID prefix (BYU → BYU-001). Then invite its first Owner with invite_org_owner.\n\nPermission: `platform.admin`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"type":{"default":"holder","type":"string","enum":["holder","athlete"]},"name":{"type":"string","minLength":2,"maxLength":160},"code":{"type":"string","pattern":"^[A-Z0-9]{2,12}$"},"domain":{"type":"string","pattern":"^[a-z0-9-]+(\\.[a-z0-9-]+)+$"}},"required":["name","code"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/admin/orgs/{org_id}/owner-invites":{"post":{"operationId":"invite_org_owner","summary":"Invite a holder's Owner (Sportsmarks admin)","description":"Invite the first Owner of an IP holder (or the athlete of an athlete holder). They get an email; only that address can accept, and accepting creates their account.\n\nPermission: `platform.admin`.","parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"org_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"email":{"type":"string","format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"}},"required":["org_id","email"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/confirmations/{token}":{"get":{"operationId":"get_confirmation","summary":"Get a pending confirmation","description":"The preview and status of a confirmation token returned by a legal or money action.\n\nPermission: `org.read`.","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/confirmations":{"get":{"operationId":"list_pending_confirmations","summary":"List pending confirmations","description":"Actions in your org waiting for a human to confirm (signatures, rate changes, rulebook publishes, manual approvals).\n\nPermission: `org.read`.","parameters":[],"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/confirmations/confirm":{"post":{"operationId":"confirm_action","summary":"Confirm a pending action","description":"Execute a previewed action. Legal and money actions need a signed-in human in the browser (agents get 403). Manual product decisions (decide_review) may be confirmed by the same agent key that requested them.\n\nPermission: `org.read`.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"token":{"type":"string","minLength":10},"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}}}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}},"/api/v1/confirmations/decline":{"post":{"operationId":"decline_action","summary":"Decline a pending action","description":"Cancel a pending confirmation without executing it.\n\nPermission: `org.read`.\n\nBrowser session only; API keys get 403.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"required":["id"]}}}},"responses":{"200":{"description":"OK"},"400":{"description":"Invalid input"},"401":{"description":"Missing or invalid API key"},"403":{"description":"Not permitted for your role"}}}}}}