Automate with the API
Use the same API Seller Central uses from your own scripts: list and update inventory, upload an inventory file, download open orders, post tracking, refund an item.
Everything Seller Central does, it does through the Bookface API, and your own scripts can call the same endpoints. A nightly job that pushes your inventory file, pulls the orders you need to ship and posts tracking numbers back is a few requests.
Get a key
- Open Settings in the Seller Central menu and click the API keys tab.
- Type a label that says what the key is for and click Create a key.
- Copy the key. It starts with
bfk_and is shown once; afterwards only its last four characters are visible.
Send the key on every request as a bearer token:
Authorization: Bearer bfk_your_key_here
A key never expires. Revoke it from the same tab the moment a script retires or you think the key has leaked; the revocation takes effect immediately. You can hold up to five active keys, so give each script its own.
All requests go to https://api.bookface.com. Bodies and responses are JSON unless the endpoint takes a file. Every request is limited to your own account; there is no way to see or change another seller's data.
Inventory
List your inventory. GET /api/inventory returns 100 items a page. Filters: q (title, author or ISBN), sku, itemCondition, includeArchived=true, needsStock=true, page.
Add a book. POST /api/inventory with the ISBN-13, condition and your quantity:
{ "isbn13": "9780131471375", "itemCondition": "GOOD", "sellerStock": 2, "sku": "SHELF-A-104", "itemDescription": "Clean copy, light shelf wear" }
Conditions are NEW, LIKE_NEW, VERY_GOOD, GOOD, ACCEPTABLE and RARE_COLLECTIBLE. Leave sku out and the listing number becomes the SKU; a SKU you set must be unique among all your listings, archived ones included. See SKUs explained.
Change an item. PUT /api/inventory/:id with any of the fields you would edit on the listing page, for example sellerStock, itemCondition, itemDescription, reqdStock, stopOrdering. POST /api/inventory/:id/archive takes it off sale; DELETE /api/inventory/:id removes a listing that has no history.
Prices are per ISBN and per marketplace. GET /api/inventory/:id/identities lists the ISBNs the item is listed under and, for each, its price on every marketplace. Set one with:
PUT /api/inventory/identities/:identityId/marketplaces/:marketplaceId
{ "price": 24.5, "isListed": true }
GET /api/inventory/marketplaces gives the marketplace ids. The Bookface listing can be priced but never unlisted; the other marketplaces only receive prices once you have connected them. See Edit a listing.
Upload a whole file. POST /api/sellers/inventory/uploads as multipart/form-data with a file field: the same Amazon Inventory Loader or Bookface CSV format the Import inventory page accepts. The response carries an upload id; GET /api/sellers/inventory/uploads/:id reports its status and the rows that were created, updated, archived or refused, with the reason for each. Rows are matched to your listings by SKU.
Orders placed on Bookface
Download what needs shipping. GET /api/sellers/orders/export?status=unshipped&format=json returns one row per copy you have to ship: order id, item id, your SKU, ISBN, title, condition, price, shipping paid, the buyer's address and the shipping speed. format=csv gives the same as a file, status=all everything, and since=2026-10-01 only orders placed after a date.
List and read orders. GET /api/orders/sellers/purchase-orders with status=UNSHIPPED or SHIPPED, search (buyer, order id or ISBN) and page; GET /api/orders/sellers/purchase-orders/:id for one order with its items.
Mark a copy shipped. PUT /api/orders/sellers/purchase-orders/:orderId/items/:itemId:
{ "isShipped": true, "shipper": "USPS", "trackingNo": "9400111899223197428501" }
The buyer gets the shipped email at once. Only copies you ship yourself can be marked this way; copies Bookface ships for you are handled on our side. See Work your orders.
Post tracking in bulk. POST /api/sellers/orders/tracking with up to 1,000 rows:
{ "rows": [ { "orderId": 104, "sku": "SHELF-A-104", "trackingNo": "9400111899223197428501", "shipper": "USPS" } ] }
Give itemId instead of sku when you have it. The response reports each row as done or refused, with the reason.
Refund an item. POST /api/sellers/orders/:orderId/items/:itemId/refund with an amount and a reason:
{ "amount": 24.5, "refundReason": "ITEM_OUT_OF_STOCK", "note": "Copy damaged on the shelf" }
Reasons: ITEM_OUT_OF_STOCK, BUYER_CANCELLED, ITEM_RETURNED, ITEM_NOT_DELIVERED, ITEM_NOT_AS_DESCRIBED, ITEM_DAMAGED, ITEM_RETURNED_UNCLAIMED, OTHER_REASON. The buyer's card is refunded, the amount comes off your balance, and a refund never restocks the copy by itself. GET /api/sellers/orders/:orderId/refunds shows how much can still be refunded on an order and what has been refunded so far. See Refunds and returns.
A nightly script, in outline
POST /api/sellers/inventory/uploadswith today's inventory file, then poll the upload until its status isdoneand log any refused rows.GET /api/sellers/orders/export?status=unshipped&format=jsonand hand the rows to whoever packs.- After the labels are printed,
POST /api/sellers/orders/trackingwith the tracking numbers.
When something goes wrong
A 401 means the key is missing, revoked or mistyped. A 400 carries an error message, and often a details list naming the field, that says what to fix. A 404 is an order or item that is not yours or does not exist. Requests are per account and ordinary volumes are fine; a script that hammers one endpoint in a tight loop will be slowed down.