GemcertX Demo

Developers

The Website API

Show a lab's certificates on its own website. A small, read-only JSON API that returns exactly what the public Verify page shows — gemological findings only, never customer names, prices or internal notes.

01

Getting started

Every lab runs its own GemcertX installation, so the API lives on that lab's own address. Requests use HTTPS and return JSON.

  1. In GemcertX, open Settings → Website API and switch the API on.
  2. Create an API key and copy it straight away — GemcertX keeps only a fingerprint of it, so it cannot be shown again.
  3. If a web page will call the API from the browser, add that site's address under Allowed origins.

Base URL

https://your-lab-address/api/v1

Endpoints

GET  /certificates
GET  /certificates/{report_no}
02

Authentication

Send the key in the X-Api-Key header on every request. The key is never accepted in the address, where it would end up in server logs and browser history.

The API is read-only and returns only public findings, but treat the key as a secret: call the API from your server where you can, and if a browser page must call it directly, restrict Allowed origins to your own site.

curl https://your-lab-address/api/v1/certificates/AGL-2609-0384 \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Accept: application/json"
const res = await fetch(
  'https://your-lab-address/api/v1/certificates/AGL-2609-0384',
  { headers: { 'X-Api-Key': process.env.GEMCERTX_KEY } }
);
const body = await res.json();
if (body.valid) console.log(body.data.variety, body.data.weight);
$ch = curl_init('https://your-lab-address/api/v1/certificates/AGL-2609-0384');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['X-Api-Key: ' . getenv('GEMCERTX_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
03

List certificates

GET /certificates returns issued certificates, newest first, a page at a time. Withdrawn certificates and drafts are never listed.

ParameterDescription
updated_sinceOnly certificates changed on or after this date, e.g. 2026-10-01. Use it to keep a copy in sync.
searchMatches the report number, identification or gem type. Up to 50 characters.
per_page1–100. Default 25.
pagePage number. Or follow links.next.

Response 200

{
  "data": [
    {
      "report_no": "AGL-2609-0384",
      "variety": "Blue Sapphire",
      "weight": "4.875",
      "weight_unit": "ct",
      …
    }
  ],
  "meta": { "current_page": 1, "last_page": 4, "per_page": 25, "total": 92 },
  "links": { "next": "https://…/api/v1/certificates?page=2", "prev": null }
}
04

Look up a certificate

GET /certificates/{report_no} answers the same question as the Verify page: is this certificate genuine and still valid?

StatusMeaning
200"valid": true with the certificate in data.
404No issued certificate with this number.
410Withdrawn by the lab — "withdrawn": true and the date. Show it as not valid.

Response 200

{
  "valid": true,
  "data": {
    "report_no": "AGL-2609-0384",
    "report_type": "cert",
    "issued_at": "2026-10-01",
    "lab": "Aurelia Gem Laboratory",
    "gem_type": "Natural Corundum",
    "identification": "Natural Corundum",
    "variety": "Blue Sapphire",
    "weight": "4.875",
    "weight_unit": "ct",
    "dimensions": "10.88 x 8.90 x 5.44 mm",
    "color": "Blue",
    "shape": "Cushion",
    "transparency": "Transparent",
    "comment": "Indications of heating",
    "image_url": "https://…/storage/gems/….webp",
    "verify_url": "https://…/verify/AGL-2609-0384?k=…",
    "updated_at": "2026-10-01T10:42:00+05:30"
  }
}

Response 410

{
  "valid": false,
  "withdrawn": true,
  "withdrawn_at": "2026-10-02",
  "message": "This certificate has been withdrawn by the laboratory and is no longer valid."
}
05

Fields

Fields the lab chose to hide on the printed certificate — weight, dimensions or colour type — come back as null, as do fields left blank. verify_url is the same link printed in the certificate's QR code.

report_noReport number
report_typeType of report
issued_atDate of issue
labIssuing laboratory
gem_type, identification, varietyIdentification
weight, weight_unitWeight, as printed
dimensionsMeasurements
color, color_typeColour
cut, shape, transparencyCut and appearance
commentReport comment
image_urlStone photo, if any
verify_urlPublic verification link
updated_atLast change, ISO 8601
06

Errors & limits

Each key may make up to 120 requests a minute. Errors return JSON with a message.

StatusMeaning
401Missing or invalid API key.
422A parameter is not valid, e.g. per_page above 100.
429Too many requests — wait a minute and try again.
503The lab has switched the API off.

Book a demo

Give every certificate the proof it deserves.

See GemcertX running with your own lab's name and logo. We set it up, bring your existing records across, and train your team.

Book a demo