Set up your listing fields

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.

From a file to fields the tools use
  1. Write one file per categoryEach field has a type and a description in plain words. The description is how Orbit and Safeguard understand the field.
  2. Upload each file to your working copyPUT /api/v1/schema-draft/categories/{category}. PCIFIC checks the file and stores it exactly as you sent it.
  3. Publish the working copyPOST /api/v1/schema-versions makes the next numbered version. Earlier versions never change.
  4. Orbit and Safeguard use the newest versionThere is nothing to switch on. The next listing or review uses it.

Before you start

  • A test key with the listing-fields permission. New test keys do not have it. Tick Set up listing fields on the key (Edit on the API keys page) or make a key with it.
  • A live key can read listing fields but is always refused (403 KEY_NOT_ALLOWED) when it tries to change them.
  • In the dashboard, the Your listing fields builder on the Shop settings page does the same thing for owners and admins, and shows each problem beside the field it is about.
  • Set your currency first if it is not GBP: send {"currency": "EUR"} to PUT /api/v1/orbit/settings. Every price field must allow it.

An example category file

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.

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."
        }
      }
    }
  }
}

The words PCIFIC reads

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.

The words PCIFIC reads
WordWhere it goesWhat it does
descriptionTop of a category fileSays in plain words which items belong in the category, up to 2,000 characters. Orbit reads it when it picks a category.
x-pcific-keywordsTop of a category fileA 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-sellerA fieldtrue 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-moneyA price fieldtrue 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.

Rules every file follows

  • Every field, at any depth, needs a description of 1 to 2,000 characters.
  • A file is at most 10 MB. Fields sit at most 32 levels deep. A field name is at most 256 characters. A field lists at most 10,000 options.
  • A category warns from 300 fields and is refused over 500, counting its parent categories' fields too. The limit can be raised for your business: contact PCIFIC support.
  • Your business can have at most 20,000 categories. A category name is 1 to 256 characters.
  • Every $ref (a pointer to a shared definition) must point inside the same file, such as #/$defs/engine. PCIFIC never fetches other files or web addresses.
  • The same key twice in one object is refused, and so is a file that starts with a byte order mark (an invisible marker some editors add).
  • Prices are never converted. A price field that lists currency options must include your business's currency (the currency setting in the Orbit settings, GBP by default).

Step 1: upload a category

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.

Upload the Phones category
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
The answer
{
  "category": "Phones",
  "parent": null,
  "fieldCount": 10,
  "warnings": []
}
An answer when a field has no description (422 SCHEMA_INVALID)
{
  "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."
    }
  ]
}

Sub-categories

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.

Upload a sub-category under Phones
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."}}}'

Step 2: look at your working copy

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.

List the working copy
curl -X GET "https://business.pcific.ai/api/v1/schema-draft" \
  -H "Authorization: Bearer $PCIFIC_TEST_KEY"
The answer
{
  "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": []
  }
}
  • updatedAt is when that category was last saved, in ISO 8601 UTC. fieldCount counts the fields in that file, without inherited fields.
  • comparison.publishedVersion is the latest published version, or null if nothing is published yet. comparison.message says which version was compared or that none exists.
  • comparison.added lists names saved in the draft but not published. comparison.changed lists names in both whose file bytes or parent differ. Saving the same file and parent again does not count as a change.
  • comparison.notInDraft lists published names missing from the draft. Publishing now would remove them. These lists and the categories are sorted by name. When nothing is published, every saved category is added and the other lists are empty.
  • The draft shows only saved work. Compare it with your planned categories to see which uploads you still need to send.
Read a saved category file
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}.

Step 3: publish it

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.

Publish
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."}'
The answer (201)
{
  "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.

Step 4: read your versions

  • GET /api/v1/schema-versions lists every version, newest first, with its publishedAt and categoryCount, and the newest version's categories in newestCategories. Before your first publish both lists are empty.
  • GET /api/v1/schema-versions/{version} lists one version's categories.
  • GET /api/v1/schema-versions/{version}/categories/{category} returns the file exactly as you sent it.
  • GET /api/v1/catalogue/status says which version Orbit and Safeguard use now, how many categories it has and when it was published.
List versions
curl -X GET "https://business.pcific.ai/api/v1/schema-versions" \
  -H "Authorization: Bearer $PCIFIC_TEST_KEY"
The answer (200)
{
  "versions": [
    {
      "version": 1,
      "publishedAt": "2026-10-26T09:30:00Z",
      "categoryCount": 2
    }
  ],
  "newestCategories": [
    {
      "category": "Phones",
      "parent": null
    },
    {
      "category": "Refurbished phones",
      "parent": "Phones"
    }
  ]
}

Changing your fields later

  • New category: upload it (with ?parent= if it sits under another), then publish.
  • Fixing a mistake: upload the corrected file for that category, then publish.
  • Removing a category: DELETE /api/v1/schema-draft/categories/{category}, then publish.
  • Each publish makes a new numbered version. Earlier versions never change, and the tools use the newest.

Export a draft or publish an earlier version again

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.

Errors

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.

Errors from listing fields
CodeHTTPWhy it happensHow to fix
SCHEMA_INVALID422The 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_LARGE413The 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_INVALID422The 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_CATEGORIES422Your 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_FULL422Your 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_PUBLISH422You 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_INVALID422The 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_FOUND404The 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_INTEGRITY500A 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_ALLOWED403The 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.

Limits

  • A category file: 10 MB. The website lets a file of this size through when you upload it to the schema-draft address.
  • Other JSON calls on this page: 16 KB.
  • Fields in one category: a warning from 300, refused over 500 (a parent's fields count).
  • Categories: 20,000. Options in one field: 10,000. Depth: 32 levels.

Words used on this page

  • JSON Schema: a standard way to describe what a piece of JSON data looks like.
  • Category: one kind of item you sell, with its own file of fields, such as Phones.
  • Working copy: the files you have uploaded but not yet published.
  • Version: a published, numbered set of categories. It never changes.
  • Percent-encoding: writing a character such as / in an address as %2F so it is not read as part of the address.