API reference

Generated from dyj-market-v1.yaml, version 1.0.0.

Base URL: https://api.dyj.one/v1

POST/market/feeds/{feedId}/items/search

List the products currently in a feed

Returns one page of the products your feed's rules select, each priced by the first rule that matches it, in a stable order — plus how many there are in all, and the currency every amount is in.

Filters narrow; they never widen. Every field in the request body is applied *on top of* your rules. There is no parameter that can reach a product your rules do not already select — asking for a category no rule covers returns an empty list, not an error.

A POST for a read is deliberate: the filters are structured, and putting them in a body keeps them out of proxy logs that sit next to your Authorization header.

Path parameters

NameTypeDescription
feedId
required
string (uuid)Your feed's public id, from the Integration tab of the feed in your dashboard. It identifies a feed; it does not authorise access — the secret key does that.

Request body (optional)

FieldTypeDescription
categoriesarray of ring | earring | necklace | bracelet | pendant | brooch | bangle | stud | hoop | drop_earring | tennis_bracelet | tennis_necklace | cuff

Restrict to these categories. Categories your rules do not cover simply match nothing.

listingPriceMinnumber

Lowest price.listingPrice to include — decimal, in the response currency, inclusive.

listingPriceMaxnumber

Highest price.listingPrice to include, same units, inclusive.

metalsarray of yellow_gold | white_gold | rose_gold | platinum | silver | sterling_silver

Restrict to pieces containing ANY of these metals.

stonesarray of diamond | sapphire | ruby | emerald | moissanite | aquamarine | topaz | amethyst | garnet | opal | tourmaline | tanzanite | none

Restrict to these primary stones. none selects pieces without a stone.

stoneOriginsarray of natural | lab_grown | none

Restrict to natural or lab-grown stones.

occasionsarray of engagement | wedding | anniversary | everyday | gift | statement

Restrict to pieces tagged with ANY of these occasions.

audiencesarray of women | men | unisex | children

Restrict to these audiences.

pageNumberinteger
default 1

1-based. A page past the end returns an empty data and the same total, not an error.

pageSizeinteger
default 50

Products per page. Fifty is the ceiling; the response echoes what applied.

The whole feed, first page

{}

Rings only, costing you at least €1,000.00

{
  "categories": [
    "ring"
  ],
  "listingPriceMin": 1000
}

The second page of fifty

{
  "pageNumber": 2,
  "pageSize": 50
}

Responses

StatusDescription
200

The current contents of the feed.

400

The request body did not validate. Unknown fields are rejected rather than ignored — a silently dropped filter would let you believe it applied.

401

Missing, malformed, unknown, or revoked key — all four answer identically, on purpose. The remedy is the same in every case: check the key, or rotate it.

402

Your DYJ plan is not live. The feed resumes the moment it is.

404

No such feed, or not yours, or disabled. Merged deliberately: an authenticated stranger must not be able to learn that a feed id exists.

429

Too many requests for this key. Limits are per key, not per IP, so adding servers does not add quota. Back off and retry; a full catalogue sync should page steadily rather than fan out.

200 example

{
  "data": [
    {
      "id": "2b0478f5-8ef3-41e0-9f1c-a0dcc9a2d993",
      "title": "Colette solitaire",
      "sku": "DYJ-M-1042",
      "specificationVersion": 1,
      "metalDetails": [
        {
          "type": "white_gold",
          "fineness": 750,
          "finish": "polished",
          "approximateWeightGrams": null
        }
      ],
      "stones": [
        {
          "id": "center-1",
          "role": "center",
          "type": "diamond",
          "origin": "lab_grown",
          "shape": "round",
          "count": 1,
          "totalCaratWeight": 1,
          "dimensionsMm": null,
          "setting": "prong",
          "component": null
        }
      ],
      "saleUnit": {
        "type": "piece",
        "pieceCount": 1
      },
      "includedComponents": [
        "mounting",
        "center_stones"
      ],
      "sizing": {
        "mode": "ring_size",
        "system": "EU",
        "unit": null,
        "options": [
          {
            "id": "eu-54",
            "value": "54"
          }
        ],
        "referenceOptionId": "eu-54"
      },
      "production": {
        "mode": "made_to_order",
        "leadTimeBusinessDays": {
          "min": 15,
          "max": 20
        }
      },
      "dimensions": {
        "bandWidthMm": 2.1
      },
      "description": "A narrow-shouldered solitaire.",
      "category": "ring",
      "tags": [
        "solitaire",
        "bridal"
      ],
      "materialsNote": "18k white gold",
      "metals": [
        "white_gold"
      ],
      "stone": "diamond",
      "stoneOrigin": "lab_grown",
      "occasions": [
        "engagement"
      ],
      "audience": "women",
      "price": {
        "listingPrice": 1500,
        "totalPrice": 1815,
        "discount": 0,
        "totalPriceInEur": 1815,
        "costTerms": {
          "taxTreatment": "quote_required",
          "shippingTreatment": "excluded"
        }
      },
      "updatedAt": "2026-08-31T18:10:43.594543+00:00",
      "photos": [
        {
          "url": "https://media.dyj.one/p/public/i/482/solitaire-product-shot-k7q.webp",
          "category": "product_shot"
        },
        {
          "url": "https://media.dyj.one/p/public/i/482/solitaire-try-on-m2x.webp",
          "category": "try_on"
        }
      ],
      "embed": {
        "configUrl": "https://dyj-server.c00.cc/viewer/v1/market/config/2b0478f5-8ef3-41e0-9f1c-a0dcc9a2d993?licenseKey=dyj_live_0123",
        "posterUrl": "https://media.dyj.one/p/public/i/482/solitaire-poster-3fa.webp"
      }
    }
  ],
  "pagination": {
    "pageNumber": 1,
    "pageSize": 50,
    "totalRecordsFound": 1
  },
  "currency": {
    "title": "Euro",
    "shortTitle": "EUR",
    "rate": 1,
    "updatedAt": "2026-09-03T09:00:00.000Z"
  }
}

400 example

{
  "message": [
    "property listingIds should not exist"
  ],
  "error": "Bad Request",
  "statusCode": 400
}

402 example

{
  "error": "plan_required",
  "message": "This account has no live plan"
}

404 example

{
  "error": "feed_not_found",
  "message": "Feed not found"
}
{
  "error": "feed_disabled",
  "message": "This feed is disabled"
}
GET/market/feeds/{feedId}/items/{listingId}

Fetch one product from a feed

Returns a single product, priced exactly as search prices it.

A product is reachable by id only if your rules still select it. A product that exists on the marketplace but is not in your feed answers 404, identically to one that does not exist at all — so this endpoint cannot be used to discover what else is on the platform.

Path parameters

NameTypeDescription
feedId
required
string (uuid)Your feed's public id, from the Integration tab of the feed in your dashboard. It identifies a feed; it does not authorise access — the secret key does that.
listingId
required
string (uuid)The product's `id` from a search response.

Responses

StatusDescription
200

The product, in the same envelope as search minus the pagination.

401

Missing, malformed, unknown, or revoked key — all four answer identically, on purpose. The remedy is the same in every case: check the key, or rotate it.

402

Your DYJ plan is not live. The feed resumes the moment it is.

404

No such product in this feed. Returned for an unknown id, a product outside your feed, and a delisted one alike.

429

Too many requests for this key. Limits are per key, not per IP, so adding servers does not add quota. Back off and retry; a full catalogue sync should page steadily rather than fan out.

200 example

{
  "data": {
    "id": "2b0478f5-8ef3-41e0-9f1c-a0dcc9a2d993",
    "title": "Colette solitaire",
    "sku": "DYJ-M-1042",
    "specificationVersion": 1,
    "metalDetails": [
      {
        "type": "white_gold",
        "fineness": 750,
        "finish": "polished",
        "approximateWeightGrams": null
      }
    ],
    "stones": [
      {
        "id": "center-1",
        "role": "center",
        "type": "diamond",
        "origin": "lab_grown",
        "shape": "round",
        "count": 1,
        "totalCaratWeight": 1,
        "dimensionsMm": null,
        "setting": "prong",
        "component": null
      }
    ],
    "saleUnit": {
      "type": "piece",
      "pieceCount": 1
    },
    "includedComponents": [
      "mounting",
      "center_stones"
    ],
    "sizing": {
      "mode": "ring_size",
      "system": "EU",
      "unit": null,
      "options": [
        {
          "id": "eu-54",
          "value": "54"
        }
      ],
      "referenceOptionId": "eu-54"
    },
    "production": {
      "mode": "made_to_order",
      "leadTimeBusinessDays": {
        "min": 15,
        "max": 20
      }
    },
    "dimensions": {
      "bandWidthMm": 2.1
    },
    "description": "A narrow-shouldered solitaire.",
    "category": "ring",
    "tags": [
      "solitaire",
      "bridal"
    ],
    "materialsNote": "18k white gold",
    "metals": [
      "white_gold"
    ],
    "stone": "diamond",
    "stoneOrigin": "lab_grown",
    "occasions": [
      "engagement"
    ],
    "audience": "women",
    "price": {
      "listingPrice": 1500,
      "totalPrice": 1815,
      "discount": 0,
      "totalPriceInEur": 1815,
      "costTerms": {
        "taxTreatment": "quote_required",
        "shippingTreatment": "excluded"
      }
    },
    "updatedAt": "2026-08-31T18:10:43.594543+00:00",
    "photos": [],
    "embed": null
  },
  "currency": {
    "title": "Euro",
    "shortTitle": "EUR",
    "rate": 1,
    "updatedAt": "2026-09-03T09:00:00.000Z"
  }
}

402 example

{
  "error": "plan_required",
  "message": "This account has no live plan"
}

404 example

{
  "error": "not_found",
  "message": "Product not found"
}
GET/health· no auth

Liveness

Unauthenticated. Reports that the API process is serving; it does not probe the database.

Responses

StatusDescription
200

Serving.

Schemas

SearchRequest

All fields optional. Every one narrows the result; none can widen it.

FieldTypeDescription
categoriesarray of ring | earring | necklace | bracelet | pendant | brooch | bangle | stud | hoop | drop_earring | tennis_bracelet | tennis_necklace | cuff

Restrict to these categories. Categories your rules do not cover simply match nothing.

listingPriceMinnumber

Lowest price.listingPrice to include — decimal, in the response currency, inclusive.

listingPriceMaxnumber

Highest price.listingPrice to include, same units, inclusive.

metalsarray of yellow_gold | white_gold | rose_gold | platinum | silver | sterling_silver

Restrict to pieces containing ANY of these metals.

stonesarray of diamond | sapphire | ruby | emerald | moissanite | aquamarine | topaz | amethyst | garnet | opal | tourmaline | tanzanite | none

Restrict to these primary stones. none selects pieces without a stone.

stoneOriginsarray of natural | lab_grown | none

Restrict to natural or lab-grown stones.

occasionsarray of engagement | wedding | anniversary | everyday | gift | statement

Restrict to pieces tagged with ANY of these occasions.

audiencesarray of women | men | unisex | children

Restrict to these audiences.

pageNumberinteger
default 1

1-based. A page past the end returns an empty data and the same total, not an error.

pageSizeinteger
default 50

Products per page. Fifty is the ceiling; the response echoes what applied.

SearchResponse

The envelope every search answers in. Every amount in data is in currency.

FieldTypeDescription
data
required
array of object

pagination
required
object

currency
required
object

The currency of every amount in the response, stated once. EUR is the only currency in v1, so rate is 1; the block exists so a second currency can arrive without the shape of a product changing.

ProductResponse

The detail envelope — search's, without pagination.

FieldTypeDescription
data
required
object

currency
required
object

The currency of every amount in the response, stated once. EUR is the only currency in v1, so rate is 1; the block exists so a second currency can arrive without the shape of a product changing.

Pagination

FieldTypeDescription
pageNumber
required
integer

The page this response is.

pageSize
required
integer

The page size that applied — what you asked for, clamped to the ceiling.

totalRecordsFound
required
integer

How many products the feed selects in all, after your filters — the number behind "page 3 of 7". Membership is live, so it can change between two pages of one walk; see the sync guide for how to read a walk whose total moved.

Currency

The currency of every amount in the response, stated once. EUR is the only currency in v1, so rate is 1; the block exists so a second currency can arrive without the shape of a product changing.

FieldTypeDescription
title
required
string

shortTitle
required
string

ISO 4217 code.

rate
required
number

Against EUR, the platform's base currency. 1 while EUR is the only currency served.

updatedAt
required
string (date-time)

When rate was last set.

Price

Decimal amounts in the response's currency. Confidential to your account — no designer and no other business sees them.

FieldTypeDescription
listingPrice
required
number

What DYJ charges you to produce this piece. Your cost, not a recommended price.

totalPrice
required
number

Your selling price, computed from listingPrice by the margin schedule of the first of your rules that matches this piece:

total = round_half_up(listing × (1 + percent/100)) + addon

DYJ never charges it — it exists so your store and your dashboard agree without you recomputing anything.

discount
required
number

Reserved. Always 0 for now; a future discount will be subtracted from totalPrice here.

totalPriceInEur
required
number

totalPrice converted to EUR at currency.rate. Equal to totalPrice while EUR is the only currency.

costTerms
required
CostTerms | null

Terms for DYJ listingPrice only, not your shopper tax/shipping policy. Null on legacy offers; quote_required is not a final delivered total.

CostTerms

FieldTypeDescription
taxTreatment
required
included | excluded | quote_required

shippingTreatment
required
included | excluded | quote_required

MetalDetail

FieldTypeDescription
type
required
yellow_gold | white_gold | rose_gold | platinum | silver | sterling_silver

fineness
required
integer

Confirmed purity in parts per thousand; 750 means 18K gold, 925 sterling silver.

finish
required
string | null

approximateWeightGrams
required
number | null

Approximate metal weight for the complete sale unit at sizing.referenceOptionId. Null means unknown.

StoneGroup

FieldTypeDescription
id
required
string

role
required
center | accent | main

type
required
diamond | sapphire | ruby | emerald | moissanite | aquamarine | topaz | amethyst | garnet | opal | tourmaline | tanzanite

origin
required
natural | lab_grown

shape
required
string

colorstring | null

Confirmed stone body color, such as white, teal, or champagne. Custom color labels remain supported. Null or absent means unknown; color does not imply natural or lab-grown origin.

count
required
integer

Number supplied in this group across the complete sale unit, including both pieces of a pair.

totalCaratWeight
required
number | null

Confirmed total for the group across the sale unit; never a per-stone weight. Null means unknown.

dimensionsMm
required
StoneDimensions | null

Individual stone dimensions, only when they apply to every stone in the group.

setting
required
string | null

component
required
string | null

Optional label identifying a piece in an asymmetric pair or set.

StoneDimensions

FieldTypeDescription
length
required
number | null

width
required
number | null

depth
required
number | null

SaleUnit

Prices, metal weights, stone counts and group carat weights cover this complete unit. piece=1, pair=2, set=2?100.

FieldTypeDescription
type
required
piece | pair | set

pieceCount
required
integer

Sizing

One fixed approved material/stone specification and price applies to every size. Fixed mode has no selectable options. Reference option anchors approximate metal weight and nominal dimensions.

FieldTypeDescription
mode
required
ring_size | length | fixed

system
required
EU | US | UK |

unit
required
mm |

options
required
array of object

referenceOptionId
required
string | null

Production

FieldTypeDescription
mode
required
made_to_order

leadTimeBusinessDays
required
object

Atelier estimate after payment and final specification confirmation, excluding shipping transit. min is no greater than max.

Dimensions

Nominal millimeter measurements per piece at sizing.referenceOptionId. Only applicable measurements are populated.

FieldTypeDescription
lengthMmnumber | null

widthMmnumber | null

heightMmnumber | null

bandWidthMmnumber | null

thicknessMmnumber | null

PhotoCategory

Where a gallery image came from. For an image the designer generated in DYJ Studio it is the generation mode they chose — the same four the Studio screen offers. Uploaded photographs, renders and the 3D poster carry their kind. A prepared reference image is other.

product_shot | try_on | lifestyle_scene | campaign_shot | product_photo | render | poster | other — one of: product_shot, try_on, lifestyle_scene, campaign_shot, product_photo, render, poster, other

Product

FieldTypeDescription
id
required
string (uuid)

Stable identifier for this product. Use it as your own catalogue key.

sku
required
string

Stable public Marketplace reference, distinct from the creator's internal catalog reference. Never changes on reapproval.

specificationVersion
required
integer | null

Reviewed specification version; null on legacy products. A price-only update keeps this version while updatedAt advances.

metalDetails
required
array | null of object

Confirmed materials, or null when no structured specification has been reviewed.

stones
required
array | null of object

Supplied homogeneous stone groups. Null means no reviewed information; [] confirms stone-free. Request stones/stoneOrigins filters still select the primary stone only.

saleUnit
required
SaleUnit | null

includedComponents
required
array | null of mounting | center_stones | accent_stones | main_stones | chain | earring_backs | clasp

Exactly what the atelier supplies. An illustrative center stone absent here and from stones is not included.

sizing
required
Sizing | null

production
required
Production | null

dimensions
required
Dimensions | null

title
required
string

descriptionstring | null

category
required
ring | earring | necklace | bracelet | pendant | brooch | bangle | stud | hoop | drop_earring | tennis_bracelet | tennis_necklace | cuff

tags
required
array of string

materialsNotestring | null

Free text from the designer, e.g. "18k white gold".

metals
required
array of yellow_gold | white_gold | rose_gold | platinum | silver | sterling_silver

Every metal in the piece; a two-tone ring lists two.

stone
required
Stone

The primary stone; none for a piece without one.

stoneOrigin
required
StoneOrigin

none exactly when stone is none.

occasions
required
array of engagement | wedding | anniversary | everyday | gift | statement

Zero or more. Empty when the designer did not say.

audience
required
women | men | unisex | children

price
required
object

Decimal amounts in the response's currency. Confidential to your account — no designer and no other business sees them.

updatedAt
required
string (date-time)

photos
required
array of object

The product gallery, in display order. Each URL is a stable public image URL: it carries no key, is cacheable (immutable — a changed image gets a new URL), and is safe to place in an <img src> on your store as-is. Whether the product is still yours to sell is answered by this API, not by the image, so keep syncing. Empty when the designer has not added gallery images.

embed
required
Embed | null

The per-product half of the interactive 3D view, or null when your account has no viewer key yet. The other half — your PUBLIC dyj_live_ key and the viewer script tag — is the same for every product and comes from your dashboard (My Account → Developer, or any embed code there). Together:

html <div class="dyj-viewer" data-license-key="{your public key}" data-config-url="{configUrl}" data-poster-url="{posterUrl}"></div> <script async src="{viewer script URL from your dashboard}"></script>

Omit the data-poster-url attribute when posterUrl is null; printed unguarded it becomes the literal "null", a request for an image by that name. Photo and poster URLs change when a reviewed gallery is approved, so render them from each sync rather than hard-coding them.

The view works only on the domains registered under My Account → Developer, and only while this product is in one of your feeds. When it leaves (delisted, blocked, no longer matching your rules) the tag shows the poster with a neutral notice — never an error, never a broken box.

Embed

FieldTypeDescription
configUrl
required
string (uri)

Product configuration for the viewer. Carries your public key already; use verbatim.

posterUrl
required
string | null (uri)

Still image shown before the 3D view loads (and instead of it when unavailable). A stable public image URL like the gallery's: no key, cacheable. null when the designer's published version has no poster — use the first photo, or omit the data-poster-url attribute.

Category

ring | earring | necklace | bracelet | pendant | brooch | bangle | stud | hoop | drop_earring | tennis_bracelet | tennis_necklace | cuff — one of: ring, earring, necklace, bracelet, pendant, brooch, bangle, stud, hoop, drop_earring, tennis_bracelet, tennis_necklace, cuff

Metal

yellow_gold | white_gold | rose_gold | platinum | silver | sterling_silver — one of: yellow_gold, white_gold, rose_gold, platinum, silver, sterling_silver

Stone

diamond | sapphire | ruby | emerald | moissanite | aquamarine | topaz | amethyst | garnet | opal | tourmaline | tanzanite | none — one of: diamond, sapphire, ruby, emerald, moissanite, aquamarine, topaz, amethyst, garnet, opal, tourmaline, tanzanite, none

StoneOrigin

natural | lab_grown | none — one of: natural, lab_grown, none

Occasion

engagement | wedding | anniversary | everyday | gift | statement — one of: engagement, wedding, anniversary, everyday, gift, statement

Audience

women | men | unisex | children — one of: women, men, unisex, children

Error

FieldTypeDescription
error
required
string

A stable machine-readable code. Branch on this, not on the message.

message
required
string

Human-readable. May be reworded without notice.