{"openapi":"3.1.0","info":{"title":"finpo API","version":"2026-10-12","description":"Products, stock, customers, sales and orders of a business on finpo. See /docs/api."},"servers":[{"url":"https://finpo.nikcano.com/api/developer/v1"}],"paths":{"/business":{"get":{"operationId":"retrieve_business","summary":"Retrieve the business","description":"The business the key belongs to: its name, its account number, the currency its money is in, and what kind of business it is.","tags":["Business"],"security":[{"bearer":[]}],"x-finpo-scope":"business:read","x-finpo-secret-key-only":false,"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"business","id":"cmv2a1b2c0001bus","name":"Adaku Mart","account_number":"85063792","currency":"NGN","kind":"provisions","livemode":true}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/locations":{"get":{"operationId":"list_locations","summary":"List locations","description":"The business’s branches: every place it sells from or keeps stock in. Most shops have one.","tags":["Locations"],"security":[{"bearer":[]}],"x-finpo-scope":"business:read","x-finpo-secret-key-only":false,"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"list","data":[{"object":"location","id":"cmv2a1b2c0001loc","name":"Victoria Island","code":"VIC","address":"12 Adeola Odeku Street","is_default":true,"active":true}],"has_more":false,"url":"/api/developer/v1/locations"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/categories":{"get":{"operationId":"list_categories","summary":"List categories","description":"The categories products are grouped in, as the shop arranged them.","tags":["Categories"],"security":[{"bearer":[]}],"x-finpo-scope":"products:read","x-finpo-secret-key-only":false,"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"list","data":[{"object":"category","id":"cmv2a1b2c0001cat","name":"Milk and beverages","parent":null}],"has_more":false,"url":"/api/developer/v1/categories"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/products":{"get":{"operationId":"list_products","summary":"List products","description":"The shop’s products, newest first. `query` finds products the way the shop’s own counter does: a barcode, a code, or a name, even typed wrong.","tags":["Products"],"security":[{"bearer":[]}],"x-finpo-scope":"products:read","x-finpo-secret-key-only":false,"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to return, 1 to 100. The default is 20.","schema":{"description":"How many to return, 1 to 100. The default is 20.","type":"integer","maximum":100,"minimum":1,"examples":[20]}},{"name":"starting_after","in":"query","required":false,"description":"The id of the last object of the page before: the next page starts after it.","schema":{"description":"The id of the last object of the page before: the next page starts after it.","type":"string","maxLength":40}},{"name":"ending_before","in":"query","required":false,"description":"The id of the first object of the page after: the page before ends before it.","schema":{"description":"The id of the first object of the page after: the page before ends before it.","type":"string","maxLength":40}},{"name":"query","in":"query","required":false,"description":"A barcode, a SKU, or words of the name. Forgiving of spelling.","schema":{"description":"A barcode, a SKU, or words of the name. Forgiving of spelling.","type":"string","maxLength":100,"examples":["peak milk"]}},{"name":"category","in":"query","required":false,"description":"Only products in this category.","schema":{"description":"Only products in this category.","type":"string","maxLength":40}},{"name":"active","in":"query","required":false,"description":"Only products on sale (true) or only those taken off sale (false).","schema":{"description":"Only products on sale (true) or only those taken off sale (false).","type":"boolean"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"list","data":[{"object":"product","id":"cmv2a1b2c0001prd","name":"Peak evaporated milk 160g","sku":"PEAK-160","brand":"Peak","kind":"good","barcodes":["6151100055512"],"category":"cmv2a1b2c0001cat","image_url":null,"active":true,"base_unit":"piece","container_size":1,"container_label":"tin","currency":"NGN","units":[{"key":"FULL","label":"Tin","quantity":1,"price":75000,"price_min":null,"price_max":null}],"created":"2026-10-12T09:00:00.000Z","updated":"2026-10-12T09:00:00.000Z"}],"has_more":false,"url":"/api/developer/v1/products"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"create_product","summary":"Create a product","description":"Adds a product, sold one at a time at one price. It is written exactly as a product added in finpo is, with its signed record, and checked against the plan’s limits. For sizes, cartons and fractions, add the product in finpo itself.","tags":["Products"],"security":[{"bearer":[]}],"x-finpo-scope":"products:write","x-finpo-secret-key-only":true,"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"What the product is called at the counter.","type":"string","maxLength":160,"examples":["Peak evaporated milk 160g"]},"price":{"description":"The price of one, in the smallest unit of the business’s currency (kobo for naira).","type":"integer","minimum":0,"examples":[75000]},"unit_label":{"description":"What one is called: \"Tin\", \"Pack\", \"Plate\". The default is \"Each\".","type":"string","maxLength":60,"examples":["Tin"]},"sku":{"description":"The shop’s own code for it. One is made up when none is sent.","type":"string","maxLength":60,"examples":["PEAK-160"]},"barcodes":{"description":"Barcodes printed on it.","type":"array","items":{"type":"string"},"maxItems":10,"examples":[["6151100055512"]]},"brand":{"description":"The maker.","type":"string","maxLength":80,"examples":["Peak"]},"category":{"description":"The id of a category.","type":"string","maxLength":40},"kind":{"description":"A thing on a shelf (the default), a plate on a menu, or a service that holds no stock.","type":"string","enum":["good","menu","service"]},"cost":{"description":"What one cost the shop. Only kept when the key has the `costs:read` scope.","type":"integer","minimum":0},"opening_quantity":{"description":"How many the shop has now. The default is none.","type":"integer","maximum":1000000,"minimum":0,"examples":[24]},"location":{"description":"The location the opening quantity is at. The default is the main one.","type":"string","maxLength":40}},"required":["name","price"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"example":{"object":"product","id":"cmv2a1b2c0001prd","name":"Peak evaporated milk 160g","sku":"PEAK-160","brand":"Peak","kind":"good","barcodes":["6151100055512"],"category":"cmv2a1b2c0001cat","image_url":null,"active":true,"base_unit":"piece","container_size":1,"container_label":"tin","currency":"NGN","units":[{"key":"FULL","label":"Tin","quantity":1,"price":75000,"price_min":null,"price_max":null}],"created":"2026-10-12T09:00:00.000Z","updated":"2026-10-12T09:00:00.000Z"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/products/{id}":{"get":{"operationId":"retrieve_product","summary":"Retrieve a product","description":"One product, with every unit it is sold in and its price.","tags":["Products"],"security":[{"bearer":[]}],"x-finpo-scope":"products:read","x-finpo-secret-key-only":false,"parameters":[{"name":"id","in":"path","required":true,"description":"The object’s id.","schema":{"description":"The object’s id.","type":"string","maxLength":40}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"product","id":"cmv2a1b2c0001prd","name":"Peak evaporated milk 160g","sku":"PEAK-160","brand":"Peak","kind":"good","barcodes":["6151100055512"],"category":"cmv2a1b2c0001cat","image_url":null,"active":true,"base_unit":"piece","container_size":1,"container_label":"tin","currency":"NGN","units":[{"key":"FULL","label":"Tin","quantity":1,"price":75000,"price_min":null,"price_max":null}],"created":"2026-10-12T09:00:00.000Z","updated":"2026-10-12T09:00:00.000Z"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/stock_levels":{"get":{"operationId":"list_stock_levels","summary":"List stock levels","description":"How much of each product is at each location, in the product’s own unit, as counted and confirmed. `pending_change` is what staff recorded and the owner has not approved yet.","tags":["Stock levels"],"security":[{"bearer":[]}],"x-finpo-scope":"stock:read","x-finpo-secret-key-only":false,"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to return, 1 to 100. The default is 20.","schema":{"description":"How many to return, 1 to 100. The default is 20.","type":"integer","maximum":100,"minimum":1,"examples":[20]}},{"name":"starting_after","in":"query","required":false,"description":"The id of the last object of the page before: the next page starts after it.","schema":{"description":"The id of the last object of the page before: the next page starts after it.","type":"string","maxLength":40}},{"name":"ending_before","in":"query","required":false,"description":"The id of the first object of the page after: the page before ends before it.","schema":{"description":"The id of the first object of the page after: the page before ends before it.","type":"string","maxLength":40}},{"name":"product","in":"query","required":false,"description":"Only this product.","schema":{"description":"Only this product.","type":"string","maxLength":40}},{"name":"location","in":"query","required":false,"description":"Only this location.","schema":{"description":"Only this location.","type":"string","maxLength":40}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"list","data":[{"object":"stock_level","id":"cmv2a1b2c0001stk","product":"cmv2a1b2c0001prd","location":"cmv2a1b2c0001loc","quantity":24,"pending_change":0,"containers":24,"unit":"piece","container_label":"tin","container_size":1,"updated":"2026-10-12T09:00:00.000Z"}],"has_more":false,"url":"/api/developer/v1/stock_levels"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/customers":{"get":{"operationId":"list_customers","summary":"List customers","description":"The shop’s customers, newest first, with their visits, points and what they owe. `query` finds a name even typed wrong, or a phone number.","tags":["Customers"],"security":[{"bearer":[]}],"x-finpo-scope":"customers:read","x-finpo-secret-key-only":true,"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to return, 1 to 100. The default is 20.","schema":{"description":"How many to return, 1 to 100. The default is 20.","type":"integer","maximum":100,"minimum":1,"examples":[20]}},{"name":"starting_after","in":"query","required":false,"description":"The id of the last object of the page before: the next page starts after it.","schema":{"description":"The id of the last object of the page before: the next page starts after it.","type":"string","maxLength":40}},{"name":"ending_before","in":"query","required":false,"description":"The id of the first object of the page after: the page before ends before it.","schema":{"description":"The id of the first object of the page after: the page before ends before it.","type":"string","maxLength":40}},{"name":"query","in":"query","required":false,"description":"A name or a phone number.","schema":{"description":"A name or a phone number.","type":"string","maxLength":100,"examples":["Ngozi"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"list","data":[{"object":"customer","id":"cmv2a1b2c0001cus","name":"Ngozi Eze","phone":"+2348031234567","email":null,"visits":12,"points":340,"currency":"NGN","balance_owed":0,"lifetime_spend":4820000,"last_visit":"2026-10-11T17:20:00.000Z","created":"2026-03-02T10:00:00.000Z"}],"has_more":false,"url":"/api/developer/v1/customers"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"create_customer","summary":"Create a customer","description":"Adds a customer. A business keeps one customer per name, so a name already on the list is refused with `resource_conflict`.","tags":["Customers"],"security":[{"bearer":[]}],"x-finpo-scope":"customers:write","x-finpo-secret-key-only":true,"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"Their name.","type":"string","maxLength":120,"examples":["Ngozi Eze"]},"phone":{"description":"Their phone number, which is how the shop finds them again.","type":"string","maxLength":30,"examples":["08031234567"]},"notes":{"description":"Anything the shop should know.","type":"string","maxLength":500}},"required":["name"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"example":{"object":"customer","id":"cmv2a1b2c0001cus","name":"Ngozi Eze","phone":"08031234567","email":null,"visits":0,"points":0,"currency":"NGN","balance_owed":0,"lifetime_spend":0,"last_visit":null,"created":"2026-10-12T09:00:00.000Z"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/customers/{id}":{"get":{"operationId":"retrieve_customer","summary":"Retrieve a customer","description":"One customer by id: their name and contacts, how often they come and what they have spent, their points, and what they owe the shop.","tags":["Customers"],"security":[{"bearer":[]}],"x-finpo-scope":"customers:read","x-finpo-secret-key-only":true,"parameters":[{"name":"id","in":"path","required":true,"description":"The object’s id.","schema":{"description":"The object’s id.","type":"string","maxLength":40}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"customer","id":"cmv2a1b2c0001cus","name":"Ngozi Eze","phone":"+2348031234567","email":null,"visits":12,"points":340,"currency":"NGN","balance_owed":0,"lifetime_spend":4820000,"last_visit":null,"created":"2026-03-02T10:00:00.000Z"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sales":{"get":{"operationId":"list_sales","summary":"List sales","description":"Sales recorded at the counter and on the shop computer, newest first, with their lines and payments. Sales cannot be written through the API: they are signed where they happen, which is what lets finpo check them.","tags":["Sales"],"security":[{"bearer":[]}],"x-finpo-scope":"sales:read","x-finpo-secret-key-only":true,"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to return, 1 to 100. The default is 20.","schema":{"description":"How many to return, 1 to 100. The default is 20.","type":"integer","maximum":100,"minimum":1,"examples":[20]}},{"name":"starting_after","in":"query","required":false,"description":"The id of the last object of the page before: the next page starts after it.","schema":{"description":"The id of the last object of the page before: the next page starts after it.","type":"string","maxLength":40}},{"name":"ending_before","in":"query","required":false,"description":"The id of the first object of the page after: the page before ends before it.","schema":{"description":"The id of the first object of the page after: the page before ends before it.","type":"string","maxLength":40}},{"name":"day_from","in":"query","required":false,"description":"The first business day, as YYYY-MM-DD.","schema":{"description":"The first business day, as YYYY-MM-DD.","type":"string","maxLength":10,"examples":["2026-10-01"]}},{"name":"day_to","in":"query","required":false,"description":"The last business day, as YYYY-MM-DD.","schema":{"description":"The last business day, as YYYY-MM-DD.","type":"string","maxLength":10,"examples":["2026-10-12"]}},{"name":"location","in":"query","required":false,"description":"Only sales at this location.","schema":{"description":"Only sales at this location.","type":"string","maxLength":40}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"list","data":[{"object":"sale","id":"cmv2a1b2c0001sal","receipt_number":"VIC-000018","location":"cmv2a1b2c0001loc","business_day":"2026-10-12","created":"2026-10-12T13:05:00.000Z","currency":"NGN","total":700000,"gross":700000,"customer":null,"voided":false,"refunded":false,"lines":[{"product":"cmv2a1b2c0001prd","unit":"PLATE","quantity":2,"unit_price":350000,"list_price":350000}],"payments":[{"method":"cash","amount":700000,"reference":null}]}],"has_more":false,"url":"/api/developer/v1/sales"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sales/{id}":{"get":{"operationId":"retrieve_sale","summary":"Retrieve a sale","description":"One sale, and whether it was cancelled or refunded since.","tags":["Sales"],"security":[{"bearer":[]}],"x-finpo-scope":"sales:read","x-finpo-secret-key-only":true,"parameters":[{"name":"id","in":"path","required":true,"description":"The object’s id.","schema":{"description":"The object’s id.","type":"string","maxLength":40}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"sale","id":"cmv2a1b2c0001sal","receipt_number":"VIC-000018","location":"cmv2a1b2c0001loc","business_day":"2026-10-12","created":"2026-10-12T13:05:00.000Z","currency":"NGN","total":700000,"gross":700000,"customer":null,"voided":false,"refunded":false,"lines":[],"payments":[]}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/orders":{"get":{"operationId":"list_orders","summary":"List orders","description":"Orders the shop has received, from its own staff, its order page, its tables and the API, newest first.","tags":["Orders"],"security":[{"bearer":[]}],"x-finpo-scope":"orders:read","x-finpo-secret-key-only":true,"parameters":[{"name":"limit","in":"query","required":false,"description":"How many to return, 1 to 100. The default is 20.","schema":{"description":"How many to return, 1 to 100. The default is 20.","type":"integer","maximum":100,"minimum":1,"examples":[20]}},{"name":"starting_after","in":"query","required":false,"description":"The id of the last object of the page before: the next page starts after it.","schema":{"description":"The id of the last object of the page before: the next page starts after it.","type":"string","maxLength":40}},{"name":"ending_before","in":"query","required":false,"description":"The id of the first object of the page after: the page before ends before it.","schema":{"description":"The id of the first object of the page after: the page before ends before it.","type":"string","maxLength":40}},{"name":"status","in":"query","required":false,"description":"Only orders in this state.","schema":{"description":"Only orders in this state.","type":"string","enum":["new","confirmed","preparing","ready","out_for_delivery","completed","cancelled"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"list","data":[{"object":"order","id":"cmv2a1b2c0001ord","number":42,"location":"cmv2a1b2c0001loc","channel":"online","fulfilment":"pickup","status":"new","customer":null,"customer_name":"Ngozi Eze","customer_phone":"+2348031234567","delivery_address":null,"due":null,"currency":"NGN","total":150000,"note":null,"lines":[{"product":"cmv2a1b2c0001prd","unit":"FULL","name":"Peak evaporated milk 160g","quantity":2,"unit_price":75000,"amount":150000}],"sale":null,"created":"2026-10-12T09:00:00.000Z","updated":"2026-10-12T09:00:00.000Z"}],"has_more":false,"url":"/api/developer/v1/orders"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"create_order","summary":"Create an order","description":"Sends an order to the shop, the way a customer’s order from its order page arrives: staff see it on the Orders board, prepare it, and take the money at the counter, where it becomes a signed sale. Prices are always the shop’s own: the order is priced by finpo from the products and units sent. Safe with a publishable key, from a shop’s own website or app.","tags":["Orders"],"security":[{"bearer":[]}],"x-finpo-scope":"orders:write","x-finpo-secret-key-only":false,"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"customer_name":{"description":"Who the order is for.","type":"string","maxLength":80,"examples":["Ngozi Eze"]},"customer_phone":{"description":"A number the shop can call.","type":"string","maxLength":20,"examples":["08031234567"]},"fulfilment":{"description":"Collected at the shop (the default) or delivered.","type":"string","enum":["pickup","delivery"]},"delivery_address":{"description":"Where to deliver it. Needed for a delivery.","type":"string","maxLength":300},"lines":{"description":"What is being ordered.","type":"array","items":{"type":"object","properties":{"product":{"description":"The product’s id.","type":"string","maxLength":40},"unit":{"description":"The key of the unit it is sold in. The default is its first unit.","type":"string","maxLength":40},"quantity":{"description":"How many.","type":"integer","maximum":9999,"minimum":1}},"required":["product","quantity"],"additionalProperties":false},"maxItems":40,"minItems":1,"examples":[[{"product":"cmv2a1b2c0001prd","unit":"FULL","quantity":2}]]},"note":{"description":"Anything the shop should know.","type":"string","maxLength":500},"location":{"description":"The location to send it to. The default is the main one.","type":"string","maxLength":40}},"required":["customer_name","customer_phone","lines"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"example":{"object":"order","id":"cmv2a1b2c0001ord","number":42,"location":"cmv2a1b2c0001loc","channel":"online","fulfilment":"pickup","status":"new","customer":null,"customer_name":"Ngozi Eze","customer_phone":"+2348031234567","delivery_address":null,"due":null,"currency":"NGN","total":150000,"note":null,"lines":[{"product":"cmv2a1b2c0001prd","unit":"FULL","name":"Peak evaporated milk 160g","quantity":2,"unit_price":75000,"amount":150000}],"sale":null,"created":"2026-10-12T09:00:00.000Z","updated":"2026-10-12T09:00:00.000Z"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/orders/{id}":{"get":{"operationId":"retrieve_order","summary":"Retrieve an order","description":"One order, with its lines and where it is now.","tags":["Orders"],"security":[{"bearer":[]}],"x-finpo-scope":"orders:read","x-finpo-secret-key-only":true,"parameters":[{"name":"id","in":"path","required":true,"description":"The object’s id.","schema":{"description":"The object’s id.","type":"string","maxLength":40}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"order","id":"cmv2a1b2c0001ord","number":42,"location":"cmv2a1b2c0001loc","channel":"online","fulfilment":"pickup","status":"new","customer":null,"customer_name":"Ngozi Eze","customer_phone":"+2348031234567","delivery_address":null,"due":null,"currency":"NGN","total":150000,"note":null,"lines":[{"product":"cmv2a1b2c0001prd","unit":"FULL","name":"Peak evaporated milk 160g","quantity":2,"unit_price":75000,"amount":150000}],"sale":null,"created":"2026-10-12T09:00:00.000Z","updated":"2026-10-12T09:00:00.000Z"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhook_endpoints":{"get":{"operationId":"list_webhook_endpoints","summary":"List webhook endpoints","description":"The addresses finpo sends events to. The signing secret is shown only when an endpoint is created.","tags":["Webhook endpoints"],"security":[{"bearer":[]}],"x-finpo-scope":"webhooks:write","x-finpo-secret-key-only":true,"parameters":[],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"list","data":[{"object":"webhook_endpoint","id":"cmv2a1b2c0001whk","url":"https://example.com/finpo/webhooks","enabled_events":["sale.recorded","order.created"],"active":true,"created":"2026-10-12T09:00:00.000Z"}],"has_more":false,"url":"/api/developer/v1/webhook_endpoints"}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"create_webhook_endpoint","summary":"Create a webhook endpoint","description":"Starts sending the chosen events to an address. The answer carries the signing secret, once: keep it, and check every delivery’s `Finpo-Signature` header with it (see Webhooks).","tags":["Webhook endpoints"],"security":[{"bearer":[]}],"x-finpo-scope":"webhooks:write","x-finpo-secret-key-only":true,"parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"description":"An https address of yours.","type":"string","maxLength":500,"examples":["https://example.com/finpo/webhooks"]},"enabled_events":{"description":"Which events to send: sale.recorded, stock.changed, item.upserted, customer.upserted, order.created.","type":"array","items":{"type":"string"},"maxItems":10,"minItems":1,"examples":[["sale.recorded","order.created"]]}},"required":["url","enabled_events"],"additionalProperties":false}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"example":{"object":"webhook_endpoint","id":"cmv2a1b2c0001whk","url":"https://example.com/finpo/webhooks","enabled_events":["sale.recorded"],"active":true,"created":"2026-10-12T09:00:00.000Z","secret":"whsec_..."}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhook_endpoints/{id}":{"delete":{"operationId":"delete_webhook_endpoint","summary":"Delete a webhook endpoint","description":"Stops sending events to that address.","tags":["Webhook endpoints"],"security":[{"bearer":[]}],"x-finpo-scope":"webhooks:write","x-finpo-secret-key-only":true,"parameters":[{"name":"id","in":"path","required":true,"description":"The object’s id.","schema":{"description":"The object’s id.","type":"string","maxLength":40}}],"responses":{"200":{"description":"OK","content":{"application/json":{"example":{"object":"webhook_endpoint","id":"cmv2a1b2c0001whk","deleted":true}}}},"default":{"description":"An error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"A secret key (fk_live_, fk_test_) or a publishable key (fkp_live_, fkp_test_)."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"type":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"},"param":{"type":"string"},"doc_url":{"type":"string"},"request_id":{"type":"string"}},"required":["type","code","message","request_id"]}}}}}}