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 the products your feed's rules select, each priced by the first rule that matches it, newest cursor last.

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 | earrings | bracelet | necklace | pendant | brooch | cufflinks | other

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

costMinMinorinteger

Minimum cost price, in cents, inclusive.

costMaxMinorinteger

Maximum cost price, in cents, inclusive.

cursorinteger

The nextCursor from the previous page.

limitinteger
default 50

The whole feed, first page

{}

Rings only, at least €1,000.00 of cost

{
  "categories": [
    "ring"
  ],
  "costMinMinor": 100000
}

The page after a previous response

{
  "cursor": 412,
  "limit": 100
}

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

{
  "items": [
    {
      "id": "2b0478f5-8ef3-41e0-9f1c-a0dcc9a2d993",
      "title": "Colette solitaire",
      "description": "A narrow-shouldered solitaire.",
      "category": "ring",
      "tags": [
        "solitaire",
        "bridal"
      ],
      "materialsNote": "18k white gold",
      "costMinor": 150000,
      "retailMinor": 181500,
      "currency": "EUR",
      "matchedRuleId": 2,
      "updatedAt": "2026-08-31T18:10:43.594543+00:00"
    }
  ],
  "nextCursor": null
}

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.

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.

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 | earrings | bracelet | necklace | pendant | brooch | cufflinks | other

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

costMinMinorinteger

Minimum cost price, in cents, inclusive.

costMaxMinorinteger

Maximum cost price, in cents, inclusive.

cursorinteger

The nextCursor from the previous page.

limitinteger
default 50

SearchResponse

FieldTypeDescription
items
required
array of object

nextCursor
required
integer | null

Pass as cursor to fetch the next page. null means this was the last page — keep paging only while it is non-null, and never assume a fixed page count.

Product

FieldTypeDescription
id
required
string (uuid)

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

title
required
string

descriptionstring | null

category
required
ring | earrings | bracelet | necklace | pendant | brooch | cufflinks | other

tags
required
array of string

materialsNotestring | null

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

costMinor
required
integer

What DYJ charges you to produce this piece, in cents. This is your cost, not a recommended price, and it is confidential to your account.

retailMinor
required
integer

Your selling price, in cents, computed from costMinor by the margin schedule of the rule named in matchedRuleId:

retail = round_half_up(cost × (1 + percent/100)) + addon

No other account can see it, and DYJ never charges it — it exists so your store and your dashboard agree without you recomputing anything.

currency
required
string

EUR only in v1.

matchedRuleId
required
integer

Which of your rules priced this product. Rules are ordered and the FIRST match wins, so this tells you why a product costs what it does.

updatedAt
required
string (date-time)

Category

ring | earrings | bracelet | necklace | pendant | brooch | cufflinks | other — one of: ring, earrings, bracelet, necklace, pendant, brooch, cufflinks, other

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.