Describe what a listing looks like in your shop, one file per category, and publish it as a numbered version.
Your listing fields are the facts a listing in your shop carries: a size on a jacket, a mileage on a car, a battery health on a phone. Orbit fills them in from a seller's photos and notes, and Safeguard checks them. You describe them in a JSON Schema (a standard way to say what a piece of JSON data looks like), with one file for each category of item you sell.
A phones category. Every field, including the fields inside the price, has a description. The category has its own description and keywords at the top. condition and battery_health are marked so that Orbit asks the seller for them. The price is written the way PCIFIC needs prices written. Save it as phones.json.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"description": "Mobile phones and smartphones, any brand.",
"x-pcific-keywords": [
"smartphone",
"cell phone",
"iPhone",
"Android phone"
],
"required": [
"title",
"description",
"brand",
"model",
"condition",
"price"
],
"properties": {
"title": {
"type": "string",
"maxLength": 80,
"description": "The listing title buyers see, up to 80 characters."
},
"description": {
"type": "string",
"description": "A short description of the phone for buyers."
},
"brand": {
"type": "string",
"description": "The phone's maker, for example Apple or Samsung."
},
"model": {
"type": "string",
"description": "The phone's model name, for example iPhone 13."
},
"storage_gb": {
"type": "integer",
"enum": [
64,
128,
256,
512,
1024
],
"description": "Storage in gigabytes."
},
"condition": {
"type": "string",
"enum": [
"New",
"Like new",
"Good",
"Fair",
"For parts"
],
"description": "The phone's condition, as one of the options. Only the seller knows this.",
"x-pcific-ask-seller": true
},
"battery_health": {
"type": "integer",
"minimum": 0,
"maximum": 100,
"description": "Battery health as a whole percent, from the phone's battery settings.",
"x-pcific-ask-seller": true
},
"price": {
"type": "object",
"description": "The asking price.",
"x-pcific-money": true,
"required": [
"amount",
"currency"
],
"properties": {
"amount": {
"type": "integer",
"description": "Price in pence."
},
"currency": {
"type": "string",
"enum": [
"GBP"
],
"description": "Currency code."
}
}
}
}
}A schema is standard JSON Schema (draft 2020-12), plus three optional words that start with x-pcific-. PCIFIC reads nothing else of its own. Which fields exist, which are required, and what values are allowed all come from the schema itself.
| Word | Where it goes | What it does |
|---|---|---|
description | Top of a category file | Says in plain words which items belong in the category, up to 2,000 characters. Orbit reads it when it picks a category. |
x-pcific-keywords | Top of a category file | A list of other words people use for the category, so a search for smartphone finds a category called Mobiles. Up to 50 words, each 1 to 60 characters. |
x-pcific-ask-seller | A field | true means Orbit must get the value from the seller and never guess or look it up. Use it for condition, size, what is included and faults. It must be true or false. |
x-pcific-money | A price field | true marks a price. The field must be an object with a whole-number amount in the smallest unit (pence or cents) and a currency code, both required, as in the example. Send 4500 for £45; decimals, exponents and text amounts are refused. If currency lists options, they must include your business's currency. |
Send the file as the body. PCIFIC checks it without changing it and stores it exactly as sent. The answer says how many fields it found, and warns when a category is getting large. A problem comes back as 422 SCHEMA_INVALID, and problems lists each one with its path and what to do.
curl -X PUT "https://business.pcific.ai/api/v1/schema-draft/categories/Phones" \
-H "Authorization: Bearer $PCIFIC_TEST_KEY" \
-H "Content-Type: application/json" \
--data-binary @phones.json{
"category": "Phones",
"parent": null,
"fieldCount": 10,
"warnings": []
}{
"error": "This schema was not saved.",
"code": "SCHEMA_INVALID",
"tryThis": "Fix each problem listed at the place shown, then send the file again.",
"problems": [
{
"path": "/properties/model",
"problem": "This field has no description.",
"tryThis": "Add a \"description\" saying in plain words what the field holds, for example \"Asking price in pence\". Safeguard and Orbit read it to understand the field."
}
]
}A category can sit under another with ?parent=. An item in the sub-category has its parent's fields as well as its own. The parent's fields count towards the limit of 500. Upload the parent as well, or publishing is refused.
curl -X PUT "https://business.pcific.ai/api/v1/schema-draft/categories/Refurbished%20phones?parent=Phones" \
-H "Authorization: Bearer $PCIFIC_TEST_KEY" \
-H "Content-Type: application/json" \
-d '{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","description":"Phones that a company has tested and repaired before resale.","properties":{"warranty_months":{"type":"integer","description":"Months of warranty the refurbisher gives."}}}'The working copy holds your saved category files. It starts empty and stays after each publish, so later you only send what changed. Read it to see what was saved before an interrupted setup.
curl -X GET "https://business.pcific.ai/api/v1/schema-draft" \
-H "Authorization: Bearer $PCIFIC_TEST_KEY"{
"categories": [
{
"category": "Phones",
"parent": null,
"fieldCount": 10,
"updatedAt": "2026-10-20T08:00:00Z"
},
{
"category": "Refurbished phones",
"parent": "Phones",
"fieldCount": 1,
"updatedAt": "2026-10-20T08:01:00Z"
}
],
"comparison": {
"publishedVersion": null,
"message": "No schema version has been published yet.",
"added": [
"Phones",
"Refurbished phones"
],
"changed": [],
"notInDraft": []
}
}curl -X GET "https://business.pcific.ai/api/v1/schema-draft/categories/Phones" \
-H "Authorization: Bearer $PCIFIC_TEST_KEY"This returns the original file byte for byte as application/schema+json, with the same ETag (a fingerprint of the saved bytes) as the published-category read. A missing category returns 404, names the category, and tells you to list the draft or save it with PUT /api/v1/schema-draft/categories/{category}.
Publishing makes the working copy the next numbered version. You can add "about", up to 2,000 characters on what your shop sells in plain words. It is saved as the Orbit about setting. This call takes an Idempotency-Key header, so it is safe to send again after a timeout.
curl -X POST "https://business.pcific.ai/api/v1/schema-versions" \
-H "Authorization: Bearer $PCIFIC_TEST_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 9d3f1c52-0b6e-4a77-8e21-5c4a7d1e3f90" \
-d '{"about": "We sell second-hand phones to people in the UK."}'{
"version": 1,
"categories": [
{
"category": "Phones",
"parent": null,
"fieldCount": 10
},
{
"category": "Refurbished phones",
"parent": "Phones",
"fieldCount": 11
}
],
"warnings": [],
"about": "We sell second-hand phones to people in the UK."
}fieldCount in a published version counts the fields an item in that category has, its parents' fields included. That is why Refurbished phones shows 11 here and 1 in the working copy.
curl -X GET "https://business.pcific.ai/api/v1/schema-versions" \
-H "Authorization: Bearer $PCIFIC_TEST_KEY"{
"versions": [
{
"version": 1,
"publishedAt": "2026-10-26T09:30:00Z",
"categoryCount": 2
}
],
"newestCategories": [
{
"category": "Phones",
"parent": null
},
{
"category": "Refurbished phones",
"parent": "Phones"
}
]
}GET /api/v1/schema-draft/export returns categories with category, parent and raw. raw is the exact file text you saved, including whitespace. Exports are limited to 16 MiB of saved files and category names. Larger drafts return 413 SCHEMA_EXPORT_TOO_LARGE: list GET /api/v1/schema-draft and download each file with GET /api/v1/schema-draft/categories/{category}, keeping its parent for restoration. To restore it to the draft, send raw as the body of PUT /api/v1/schema-draft/categories/{category}, adding ?parent when parent is not null.
POST /api/v1/schema-versions/{version}/republish copies that version as a new, latest version. It answers 201 with version, publishedAt and categories. Existing versions and the current draft stay as they are. This restores listing fields only; shop and tool settings are separate. An unknown version answers 404 with instructions to choose from GET /api/v1/schema-versions. Published versions cannot be deleted, because active tool work can still refer to them.
Every error is a JSON body with error, code, tryThis and sometimes problems. These are the ones listing fields add. The errors any address can return are on the Errors, limits and retries page.
| Code | HTTP | Why it happens | How to fix |
|---|---|---|---|
SCHEMA_INVALID | 422 | The file is not saved because something in it breaks a rule: it is not valid JSON, not a valid JSON Schema, a field has no description, a price is not written the right way, a keyword is wrong, or it has more fields than allowed. problems lists each one with its path. | Fix each place listed in problems, using its tryThis, then upload the file again. Nothing in your working copy changed. |
SCHEMA_TOO_LARGE | 413 | The file for one category is over 10 MB. | Move fields that only some items need into sub-categories, and remove definitions nothing uses, so each file is 10 MB or smaller. |
CATEGORY_INVALID | 422 | The category name or its parent is empty, over 256 characters, not valid text, or the category is its own parent. | Use a name of 1 to 256 characters. Percent-encode it in the address, so Vehicles/Cars is Vehicles%2FCars. Leave out ?parent for a main category. |
TOO_MANY_CATEGORIES | 422 | Your working copy would hold more than 20,000 categories. | Delete categories you no longer use from the working copy, or contact PCIFIC support about your catalogue. |
SCHEMA_STORAGE_FULL | 422 | Your business would store more than 200 MB or 100,000 listing field files across its shops, working copies and published versions together. Nothing was saved. | Delete categories you no longer use with DELETE /api/v1/schema-draft/categories/{category}. A file no published version uses is removed at once, freeing its space. If you still need more room, contact PCIFIC support. |
NOTHING_TO_PUBLISH | 422 | You tried to publish a working copy with no categories in it. | Upload at least one category with PUT /api/v1/schema-draft/categories/{category}, then publish again. |
PUBLISH_INVALID | 422 | The categories do not fit together: a parent is missing, parents loop back on themselves, a category has too many fields once its parents' fields are counted, or a sub-category adds a field that a parent forbids with additionalProperties false. | Fix each problem listed, then publish again. Your working copy and earlier versions are unchanged. |
NOT_FOUND | 404 | The category is not in your working copy, or the version or category is not in that version. | Check the name, capitals included. GET /api/v1/schema-draft lists your working copy and GET /api/v1/schema-versions/{version} lists a version. |
SCHEMA_INTEGRITY | 500 | A stored file no longer matches its fingerprint, so PCIFIC would not send it. | Contact PCIFIC support with the version and category in the address. Your other versions are unaffected. |
KEY_NOT_ALLOWED | 403 | The key is a test key without the listing-fields permission, or it is a live key trying to change listing fields. | Tick Set up listing fields on a test key, or use the dashboard. A live key can read listing fields but never change them. |