{"openapi":"3.1.0","info":{"title":"FFL Bridge API","version":"1.0.0","description":"FFL dealer locator and checkout-selection API for firearm ecommerce, custom storefronts, internal fulfillment tools, and embedded checkout widgets.","contact":{"name":"FFL Bridge Support","url":"https://fflbridge.com/contact"}},"servers":[{"url":"https://fflbridge.com","description":"Production"}],"tags":[{"name":"Search","description":"Find nearby FFL dealers"},{"name":"Orders","description":"Attach a selected FFL to an order workflow"},{"name":"Usage","description":"Monitor API consumption"}],"security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"paths":{"/api/v1/search":{"get":{"tags":["Search"],"summary":"Search FFL dealers","description":"Authenticated FFL search for custom storefronts, checkout flows, dealer lookup pages, and fulfillment tools.","security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"$ref":"#/components/parameters/zip"},{"$ref":"#/components/parameters/city"},{"$ref":"#/components/parameters/state"},{"$ref":"#/components/parameters/lat"},{"$ref":"#/components/parameters/lng"},{"$ref":"#/components/parameters/radius"},{"$ref":"#/components/parameters/limit"},{"name":"acceptsTransfers","in":"query","required":false,"schema":{"type":"boolean"},"description":"Filter for dealers marked as accepting transfers."}],"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/public/search":{"get":{"tags":["Search"],"summary":"Public widget search","description":"Rate-limited public search endpoint for embedded customer-facing experiences. Dealer email is intentionally omitted from this response.","security":[],"parameters":[{"$ref":"#/components/parameters/zip"},{"$ref":"#/components/parameters/lat"},{"$ref":"#/components/parameters/lng"},{"$ref":"#/components/parameters/radius"},{"$ref":"#/components/parameters/limit"}],"responses":{"200":{"description":"Public search results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api/v1/orders":{"get":{"tags":["Orders"],"summary":"List FFL selection orders","security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"fflId","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"customerEmail","in":"query","required":false,"schema":{"type":"string","format":"email"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Orders with selected FFL details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderListResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Orders"],"summary":"Create an order with selected FFL","security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrderRequest"}}}},"responses":{"201":{"description":"Order created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrderResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"description":"FFL not found"}}}},"/api/v1/usage":{"get":{"tags":["Usage"],"summary":"Get current API usage","security":[{"BearerAuth":[]},{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Usage summary and history","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}}},"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"Use Authorization: Bearer YOUR_API_KEY."},"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Alternative API key header."}},"parameters":{"zip":{"name":"zip","in":"query","required":false,"schema":{"type":"string","pattern":"^\\d{5}$","example":"32174"},"description":"Five-digit ZIP code. Provide zip, city/state, or lat/lng."},"city":{"name":"city","in":"query","required":false,"schema":{"type":"string","example":"Ormond Beach"}},"state":{"name":"state","in":"query","required":false,"schema":{"type":"string","minLength":2,"maxLength":2,"example":"FL"}},"lat":{"name":"lat","in":"query","required":false,"schema":{"type":"number","minimum":-90,"maximum":90,"example":29.2858}},"lng":{"name":"lng","in":"query","required":false,"schema":{"type":"number","minimum":-180,"maximum":180,"example":-81.0559}},"radius":{"name":"radius","in":"query","required":false,"schema":{"type":"number","minimum":1,"maximum":500,"default":25}},"limit":{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}},"schemas":{"ApiError":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"object","properties":{"code":{"type":"string","example":"INVALID_QUERY"},"message":{"type":"string","example":"Must provide zip, city+state, or lat+lng"}}}}},"FflDealer":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"licenseNumber":{"type":"string"},"licenseType":{"type":"string"},"businessName":{"type":"string"},"tradeName":{"type":["string","null"]},"address":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zip":{"type":"string"},"phone":{"type":["string","null"]},"email":{"type":["string","null"]},"latitude":{"type":["number","null"]},"longitude":{"type":["number","null"]},"distance":{"type":"number"},"acceptsTransfers":{"type":"boolean"},"transferFee":{"type":["string","null"]},"isPreferred":{"type":"boolean"},"isRegistered":{"type":"boolean"}}},"SearchResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/FflDealer"}},"total":{"type":"integer"},"query":{"type":"object","properties":{"center":{"type":"object","properties":{"lat":{"type":"number"},"lng":{"type":"number"}}},"radius":{"type":"number"}}}}}}},"CreateOrderRequest":{"type":"object","required":["customerEmail","customerName","fflId"],"properties":{"customerEmail":{"type":"string","format":"email"},"customerName":{"type":"string"},"customerPhone":{"type":"string"},"fflId":{"type":"string","format":"uuid"},"itemDescription":{"type":"string"},"itemSku":{"type":"string"},"externalOrderId":{"type":"string"},"notes":{"type":"string"},"metadata":{"type":"object","additionalProperties":true},"sendCustomerEmail":{"type":"boolean","default":true},"sendFflEmail":{"type":"boolean","default":true}}},"CreateOrderResponse":{"type":"object","additionalProperties":true},"OrderListResponse":{"type":"object","additionalProperties":true},"UsageResponse":{"type":"object","additionalProperties":true}},"responses":{"BadRequest":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"Unauthorized":{"description":"Missing or invalid API key"},"RateLimited":{"description":"Rate limit exceeded"}}}}