MasterDB Business Machine API (1.0.0)

Download OpenAPI specification:

URL: https://docs.masterdb.ai License: LicenseRef-MasterDB

What a business's own systems call to publish, read back and audit what they published.

The business machine API, for a business's own integration, a Shopify-style connector or an agency's feed — ADL Path A. There is no bearer token: every request is signed with RFC 9421 by an integration key the business generated and registered (tag="mdb-push"), and what authorises that key is a publishing mandate an admin sealed with their passkey, scoped to record types and countries and valid for at most 92 days.

Reads — the catalogue read-back, push attempts and analytics — are signed with the tag mdb-business-read instead, and need a registered key but no mandate.

Sealed, or not published: every record is sealed by the business, a batch with one Merkle root, and a record whose seal does not verify is refused with a reason that names the seal. A push replaces the record; there is no merge on this path. Nothing publishes without a seal, and a bare DELETE is refused.

Publishing

Sealed batch pushes, withdrawals and deletes.

Push a sealed batch

Publishes a batch of records of one type, each exactly the bytes the business sealed, under one batch seal: a Merkle root over the records' raw bytes signed with the business's own key, carrying the per-key sequence number seq that must be greater than the last accepted one (so a stolen key cannot roll a price back by replaying an old seal) and a sealed_at within five minutes of receipt. Each record is validated with every reason at once and answered accepted, updated or rejected; a push replaces the record it names. A push that would move more than a fifth of the catalogue's prices is held for the owner (the price-shock hold). Only products is published through this route.

Every record is also held to the scope rule (text naming another company or brand, or directing how other sources are treated, is scope_violation; a brand the business sells belongs in its Business & Brand Identity file's brands_sold) and to a malware and phishing check (url_flagged), and a display_domain must be its destination_url's own host (display_domain_mismatch) — each a per-record rejection, never the batch's.

Back-pressure: the per-key caps stamped on the mandate — records per hour and bytes per day — are judged before the body is parsed, and a request over either is answered 429 rate_limited with Retry-After. A mandate with a source allow-list (CIDR ranges and AS numbers) is honoured only from inside it (403 source_not_allowed).

Accepted, then processed. Everything that must refuse a batch is checked before the answer: the request signature, the key, the mandate and its caps, the verified business, the batch seal, its Merkle root over the records, the certificate, the AI policy version, seq, and the business's fair use. Then:

  • up to 50 records are processed inside the request and answered 200 with every outcome (PublishOutcome), as before;
  • 51 to 10,000 records are stored for processing and answered 202 at once with the push's status (PushStatus) and a Location header: poll GET /v1/pushes/{push_id} until state is complete (or held, or failed). The records are checked and published in chunks of 200 in the background; a notice tells the business's owners and admins when it finishes.

If background processing cannot be reached, a push of up to 500 records is processed inside its request (200). A larger one is answered 503 with Retry-After: 60 and retry_after_seconds: send the same batch again later; a batch that was already accepted is kept and resumes. For more than 10,000 records, upload a bulk file (POST /v1/bulk-uploads, then POST /v1/bulk-imports).

A push that does not answer, or stops (a timeout, a dropped connection, a 5xx, a failed status): every record of the batch has a row in GET /v1/push-attempts and on its status — rejected with its reasons, or pending — and each pending row becomes accepted, updated or held in the same commit that publishes (or holds) its record. Sending the exact batch again (the same batch_seal and records, a new request signature — accepted after the five-minute sealed_at window too, since it was accepted before) resumes it: the records it already settled keep their outcome, the rest are completed, and nothing is published twice. A push still being processed is only reported. Any other batch under the same seq is refused (seq_not_increasing).

Authorizations:
mdbRequestSignature
path Parameters
type
required
string (PathRecordType)
Enum: "products" "business-files" "events" "jobs" "updates"
Example: products

The record type. Only products is published through this route.

header Parameters
MDB-Sandbox-Key
string [ 1 .. 8192 ] characters
Example: mdb_sbxk1.eyJ2IjoxLCJraW5kIjoicmV0cmlldmFsIn0.c2lnbmF0dXJl

Sandbox only. The sandbox_key_grant the portal answered when the key was taken there: MasterDB's signed statement of the key and its party, which holds no secret. The sandbox does not know a key taken in the portal until a request carries its grant: the first signed request with it creates the matching party in the sandbox and registers the key there, and is then verified like any other. Send it on every sandbox request: without it the first request with a new key is refused 401 key_unknown. A key production has revoked stays refused with its grant. Production ignores the header.

Idempotency-Key
required
string [ 1 .. 257 ] characters
Example: 5f2b8c1e-7d3a-4e8f-9b6c-2a1d0e9f8c7b

Required on every POST that creates something. 1–255 printable ASCII characters. The same key with the same request replays the first answer; with a different request it is idempotency_key_reused (422); while the first is still in flight it is idempotency_in_progress (409).

Request Body schema: application/json
required
required
object (BatchSealEnvelope)
records
required
Array of strings [ 1 .. 10000 ] items [ items <= 204800 characters ]

At most 10,000 records and 32 MiB of request body; 50 or fewer are answered inline (200), more are accepted and processed in the background (202).

Responses

Request samples

Content type
application/json
{
  • "batch_seal": {
    },
  • "records": [
    ]
}

Response samples

Content type
application/json
{
  • "batch_id": "bat_7d3a4e8f9b6c",
  • "seq": 42,
  • "held": false,
  • "results": [
    ]
}

Withdraw a record, sealed

Takes a record out of serving with a tiny sealed document {record_id, action: withdraw, at} signed by the business — never an HTTP verb on a bare id. The record of truth is never removed and history stays; the published pointer moves and the fan-out removes the rows and mirror documents from every region within seconds.

Authorizations:
mdbRequestSignature
path Parameters
type
required
string (PathRecordType)
Enum: "products" "business-files" "events" "jobs" "updates"
Example: products

The record type. Only products is published through this route.

header Parameters
MDB-Sandbox-Key
string [ 1 .. 8192 ] characters
Example: mdb_sbxk1.eyJ2IjoxLCJraW5kIjoicmV0cmlldmFsIn0.c2lnbmF0dXJl

Sandbox only. The sandbox_key_grant the portal answered when the key was taken there: MasterDB's signed statement of the key and its party, which holds no secret. The sandbox does not know a key taken in the portal until a request carries its grant: the first signed request with it creates the matching party in the sandbox and registers the key there, and is then verified like any other. Send it on every sandbox request: without it the first request with a new key is refused 401 key_unknown. A key production has revoked stays refused with its grant. Production ignores the header.

Idempotency-Key
required
string [ 1 .. 257 ] characters
Example: 5f2b8c1e-7d3a-4e8f-9b6c-2a1d0e9f8c7b

Required on every POST that creates something. 1–255 printable ASCII characters. The same key with the same request replays the first answer; with a different request it is idempotency_key_reused (422); while the first is still in flight it is idempotency_in_progress (409).

Request Body schema: application/json
required
document_base64
required
string <base64>

The exact bytes of {"record_id": …, "action": "withdraw" | "delete", "at": …}.

required
object (SealEnvelope)

A Path B seal (one record, sealed by a person's passkey). Format 2 (seal.v2); format 1 (seal.v1) is still verified.

Responses

Request samples

Content type
application/json
{
  • "document_base64": "eyJyZWNvcmRfaWQiOiJtZGJfZHE1am5xYXRuZW1ucWo0ZzN4bWd6Z3BvaWsiLCJhY3Rpb24iOiJ3aXRoZHJhdyJ9",
  • "seal": {
    }
}

Response samples

Content type
application/json
{
  • "record_id": "mdb_dq5jnqatnemnqj4g3xmgzgpoik",
  • "action": "withdraw",
  • "live_in": [ ]
}

Delete a record, sealed

Deletes a record with a sealed document {record_id, action: delete, at}. Deletion means deletion: the record leaves serving in seconds and its bytes are purged from the master copy and backups within 30 days; only its fingerprints — the hashes and log leaves — stay, which is what lets the public disavowal check still say when a record with that hash was live.

Authorizations:
mdbRequestSignature
path Parameters
type
required
string (PathRecordType)
Enum: "products" "business-files" "events" "jobs" "updates"
Example: products

The record type. Only products is published through this route.

header Parameters
MDB-Sandbox-Key
string [ 1 .. 8192 ] characters
Example: mdb_sbxk1.eyJ2IjoxLCJraW5kIjoicmV0cmlldmFsIn0.c2lnbmF0dXJl

Sandbox only. The sandbox_key_grant the portal answered when the key was taken there: MasterDB's signed statement of the key and its party, which holds no secret. The sandbox does not know a key taken in the portal until a request carries its grant: the first signed request with it creates the matching party in the sandbox and registers the key there, and is then verified like any other. Send it on every sandbox request: without it the first request with a new key is refused 401 key_unknown. A key production has revoked stays refused with its grant. Production ignores the header.

Idempotency-Key
required
string [ 1 .. 257 ] characters
Example: 5f2b8c1e-7d3a-4e8f-9b6c-2a1d0e9f8c7b

Required on every POST that creates something. 1–255 printable ASCII characters. The same key with the same request replays the first answer; with a different request it is idempotency_key_reused (422); while the first is still in flight it is idempotency_in_progress (409).

Request Body schema: application/json
required
document_base64
required
string <base64>

The exact bytes of {"record_id": …, "action": "withdraw" | "delete", "at": …}.

required
object (SealEnvelope)

A Path B seal (one record, sealed by a person's passkey). Format 2 (seal.v2); format 1 (seal.v1) is still verified.

Responses

Request samples

Content type
application/json
{
  • "document_base64": "eyJyZWNvcmRfaWQiOiJtZGJfZHE1am5xYXRuZW1ucWo0ZzN4bWd6Z3BvaWsiLCJhY3Rpb24iOiJkZWxldGUifQ==",
  • "seal": {
    }
}

Response samples

Content type
application/json
{
  • "record_id": "mdb_dq5jnqatnemnqj4g3xmgzgpoik",
  • "action": "withdraw",
  • "live_in": [ ]
}

Catalogue

Read back what you published — a manifest, not an export.

Read back your catalogue manifest

The manifest of what your business has published — ids, your own business_product_id, last_updated and source (manual, import or api) — in cursor pages, rate-limited above 1,000 records. It is how a connector reconciles its own state with MasterDB's; it is not an export, and the only full-record path is the account export in the Business Portal.

Authorizations:
mdbRequestSignature
query Parameters
cursor
string <= 512 characters

The opaque next_cursor of the previous page.

type
string (RecordType)
Enum: "products" "business_files" "events" "jobs" "updates"
Example: type=products

The five published types, as collection names.

header Parameters
MDB-Sandbox-Key
string [ 1 .. 8192 ] characters
Example: mdb_sbxk1.eyJ2IjoxLCJraW5kIjoicmV0cmlldmFsIn0.c2lnbmF0dXJl

Sandbox only. The sandbox_key_grant the portal answered when the key was taken there: MasterDB's signed statement of the key and its party, which holds no secret. The sandbox does not know a key taken in the portal until a request carries its grant: the first signed request with it creates the matching party in the sandbox and registers the key there, and is then verified like any other. Send it on every sandbox request: without it the first request with a new key is refused 401 key_unknown. A key production has revoked stays refused with its grant. Production ignores the header.

Responses

Response samples

Content type
application/json
{
  • "entries": [
    ],
  • "next_cursor": "eyJhZnRlciI6Im1kYl9kcTVqIn0="
}

Read back one of your records

One of your own records as stored, by MasterDB's record id or by your own business_product_id — the bytes you sealed, the seal, the sidecar and where it is live. Only your own business's records are ever returned here.

Authorizations:
mdbRequestSignature
path Parameters
record_id
required
string [ 1 .. 256 ] characters
Example: mdb_dq5jnqatnemnqj4g3xmgzgpoik

A MasterDB record id, or your business_product_id (URL-encoded).

header Parameters
MDB-Sandbox-Key
string [ 1 .. 8192 ] characters
Example: mdb_sbxk1.eyJ2IjoxLCJraW5kIjoicmV0cmlldmFsIn0.c2lnbmF0dXJl

Sandbox only. The sandbox_key_grant the portal answered when the key was taken there: MasterDB's signed statement of the key and its party, which holds no secret. The sandbox does not know a key taken in the portal until a request carries its grant: the first signed request with it creates the matching party in the sandbox and registers the key there, and is then verified like any other. Send it on every sandbox request: without it the first request with a new key is refused 401 key_unknown. A key production has revoked stays refused with its grant. Production ignores the header.

Responses

Response samples

Content type
application/json
{
  • "record_id": "mdb_dq5jnqatnemnqj4g3xmgzgpoik",
  • "business_product_id": "TR-5521",
  • "type": "products",
  • "record": {
    },
  • "seal": {
    },
  • "live_in": [
    ],
  • "last_updated": "2026-09-30T08:15:00.000Z",
  • "source": "api"
}

Push attempts

The ingestion audit.

Read the ingestion audit

Every row a push tried to publish in a window, with its outcome and reason — a seal failure is its own category, distinct from a validation failure — so a rejected push is visible within seconds.

Authorizations:
mdbRequestSignature
query Parameters
from
string
Example: from=2026-10-01T00:00:00Z

Start of the window, inclusive (RFC 3339 UTC or a date).

to
string
Example: to=2026-10-02T00:00:00Z

End of the window, exclusive (RFC 3339 UTC or a date).

status
string
Enum: "accepted" "updated" "rejected" "held" "pending"
Example: status=rejected
cursor
string <= 512 characters

The opaque next_cursor of the previous page.

header Parameters
MDB-Sandbox-Key
string [ 1 .. 8192 ] characters
Example: mdb_sbxk1.eyJ2IjoxLCJraW5kIjoicmV0cmlldmFsIn0.c2lnbmF0dXJl

Sandbox only. The sandbox_key_grant the portal answered when the key was taken there: MasterDB's signed statement of the key and its party, which holds no secret. The sandbox does not know a key taken in the portal until a request carries its grant: the first signed request with it creates the matching party in the sandbox and registers the key there, and is then verified like any other. Send it on every sandbox request: without it the first request with a new key is refused 401 key_unknown. A key production has revoked stays refused with its grant. Production ignores the header.

Responses

Response samples

Content type
application/json
{
  • "attempts": [
    ]
}

Pushes

A push's status while it is processed, and the bulk-file route for very large loads.

Read a push's status and its per-record outcomes

A push or bulk import accepted then processed: its totals, its progress and a page of its records' outcomes in leaf order (100 a page; next_cursor for the next). With outcome, only the records with that outcome — e.g. rejected, to fix and send again. Poll every poll_after_seconds while it is present. A push that has completed no step for ten minutes carries stalled: true and a resume instruction (send the exact batch again — a bulk import, the same import request again; what it already published is not published twice). Signed with mdb-business-read: any live integration key of the business may read it.

Authorizations:
mdbRequestSignature
path Parameters
push_id
required
string (PushId) ^bat_[0-9a-f]{24}$
Example: bat_7d3a4e8f9b6c1a2b3c4d5e6f

A push (or bulk import) — the same id as its batch_id.

query Parameters
outcome
string
Enum: "accepted" "updated" "rejected" "held" "pending"
Example: outcome=rejected
cursor
string <= 512 characters

The opaque next_cursor of the previous page.

header Parameters
MDB-Sandbox-Key
string [ 1 .. 8192 ] characters
Example: mdb_sbxk1.eyJ2IjoxLCJraW5kIjoicmV0cmlldmFsIn0.c2lnbmF0dXJl

Sandbox only. The sandbox_key_grant the portal answered when the key was taken there: MasterDB's signed statement of the key and its party, which holds no secret. The sandbox does not know a key taken in the portal until a request carries its grant: the first signed request with it creates the matching party in the sandbox and registers the key there, and is then verified like any other. Send it on every sandbox request: without it the first request with a new key is refused 401 key_unknown. A key production has revoked stays refused with its grant. Production ignores the header.

Responses

Response samples

Content type
application/json
{
  • "push_id": "bat_7d3a4e8f9b6c1a2b3c4d5e6f",
  • "batch_id": "bat_7d3a4e8f9b6c1a2b3c4d5e6f",
  • "type": "products",
  • "seq": 42,
  • "source": "api",
  • "mode": "queued",
  • "state": "processing",
  • "held": false,
  • "held_reasons": [ ],
  • "records": 8000,
  • "counts": {
    },
  • "progress": {
    },
  • "received_at": "2026-10-03T14:02:11.482Z",
  • "updated_at": "2026-10-03T14:04:40.120Z",
  • "completed_at": null,
  • "error": null,
  • "status_url": "/v1/pushes/bat_7d3a4e8f9b6c1a2b3c4d5e6f",
  • "poll_after_seconds": 5,
  • "results": [
    ],
  • "next_cursor": "eyJhZnRlciI6IjE4In0"
}

Get a signed upload for a bulk file

The bulk-file route for very large loads, step 1: a signed upload (valid one hour) for one file of up to 100,000 records and 256 MiB. The file is newline-delimited: one record a line, each line the base64 of the record's exact bytes (application/x-ndjson); line i is leaf i of the batch seal's Merkle tree. POST the file to url as multipart/form-data with every member of fields, then the file as file. The key needs a live mandate for the record type. Uploaded files are deleted after 7 days, or as soon as their import completes.

Answered 503 with Retry-After (60 seconds) and reason: staging_unavailable where the upload area cannot be written, and 503 with a longer Retry-After where bulk import is not available.

Authorizations:
mdbRequestSignature
header Parameters
MDB-Sandbox-Key
string [ 1 .. 8192 ] characters
Example: mdb_sbxk1.eyJ2IjoxLCJraW5kIjoicmV0cmlldmFsIn0.c2lnbmF0dXJl

Sandbox only. The sandbox_key_grant the portal answered when the key was taken there: MasterDB's signed statement of the key and its party, which holds no secret. The sandbox does not know a key taken in the portal until a request carries its grant: the first signed request with it creates the matching party in the sandbox and registers the key there, and is then verified like any other. Send it on every sandbox request: without it the first request with a new key is refused 401 key_unknown. A key production has revoked stays refused with its grant. Production ignores the header.

Idempotency-Key
required
string [ 1 .. 257 ] characters
Example: 5f2b8c1e-7d3a-4e8f-9b6c-2a1d0e9f8c7b

Required on every POST that creates something. 1–255 printable ASCII characters. The same key with the same request replays the first answer; with a different request it is idempotency_key_reused (422); while the first is still in flight it is idempotency_in_progress (409).

Request Body schema: application/json
required
record_type
string (RecordType)
Enum: "products" "business_files" "events" "jobs" "updates"

The five published types, as collection names.

Responses

Request samples

Content type
application/json
{
  • "record_type": "products"
}

Response samples

Content type
application/json
{
  • "upload_id": "bup_5f1c0e9a8b7d6c5b4a3f2e1d",
  • "record_type": "products",
  • "fields": {
    },
  • "content_type": "application/x-ndjson",
  • "max_bytes": 268435456,
  • "max_records": 100000,
  • "expires_at": "2026-10-03T15:02:11.482Z"
}

Import an uploaded bulk file under its batch seal

The bulk-file route, step 2: the uploaded file's upload_id and the batch seal over its records — the same seal as a push's (tree_size the number of lines, root the Merkle root over the records' raw bytes, a seq above the key's last). The seal, the key, the mandate and its caps (over the file's bytes and records), the certificate, the AI policy version and fair use are checked here; the file is then read once in the background, and if its records are not exactly the ones the seal names the import is failed with seal_invalid before any record is checked. Otherwise it is processed as a queued push: poll GET /v1/pushes/{push_id}. The same request again answers the import's status, and resumes one that stopped. Answered 503 with Retry-After where bulk import is not available (the upload area cannot be written, reason: staging_unavailable), and where background processing cannot be reached (the import is kept: send the same request again).

Authorizations:
mdbRequestSignature
header Parameters
MDB-Sandbox-Key
string [ 1 .. 8192 ] characters
Example: mdb_sbxk1.eyJ2IjoxLCJraW5kIjoicmV0cmlldmFsIn0.c2lnbmF0dXJl

Sandbox only. The sandbox_key_grant the portal answered when the key was taken there: MasterDB's signed statement of the key and its party, which holds no secret. The sandbox does not know a key taken in the portal until a request carries its grant: the first signed request with it creates the matching party in the sandbox and registers the key there, and is then verified like any other. Send it on every sandbox request: without it the first request with a new key is refused 401 key_unknown. A key production has revoked stays refused with its grant. Production ignores the header.

Idempotency-Key
required
string [ 1 .. 257 ] characters
Example: 5f2b8c1e-7d3a-4e8f-9b6c-2a1d0e9f8c7b

Required on every POST that creates something. 1–255 printable ASCII characters. The same key with the same request replays the first answer; with a different request it is idempotency_key_reused (422); while the first is still in flight it is idempotency_in_progress (409).

Request Body schema: application/json
required
upload_id
required
string^bup_[0-9a-f]{24}$
required
object (BatchSealEnvelope)

Responses

Request samples

Content type
application/json
{
  • "upload_id": "bup_5f1c0e9a8b7d6c5b4a3f2e1d",
  • "batch_seal": {
    }
}

Response samples

Content type
application/json
{
  • "push_id": "bat_7d3a4e8f9b6c1a2b3c4d5e6f",
  • "batch_id": "bat_7d3a4e8f9b6c1a2b3c4d5e6f",
  • "type": "products",
  • "seq": 42,
  • "source": "bulk",
  • "mode": "queued",
  • "state": "queued",
  • "held": false,
  • "held_reasons": [ ],
  • "records": 8000,
  • "counts": {
    },
  • "progress": {
    },
  • "received_at": "2026-10-03T14:02:11.482Z",
  • "updated_at": "2026-10-03T14:04:40.120Z",
  • "completed_at": null,
  • "error": null,
  • "status_url": "/v1/pushes/bat_7d3a4e8f9b6c1a2b3c4d5e6f",
  • "poll_after_seconds": 5
}

Seal context

What a seal must name — the certificate and the AI policy version in force.

Read the certificate and the AI policy version a seal must name

What the next seal must name: cert_id, the business's certificate in force (a seal naming any other is refused), and ai_policy_version, the business's own AI policy version in force — the live generation of its AI policy record, 0 before one is sealed. A seal binds the version in force at sealed_at (seal format 2's ai_policy_version; format 1 named terms_version); an AI policy record's own seal names the version it creates, next_ai_policy_version. Before this read a pushing system learned the version only from a refusal (seal_invalid with an ai_policy_version extension). Any live integration key of the business may read it.

Authorizations:
mdbRequestSignature
header Parameters
MDB-Sandbox-Key
string [ 1 .. 8192 ] characters
Example: mdb_sbxk1.eyJ2IjoxLCJraW5kIjoicmV0cmlldmFsIn0.c2lnbmF0dXJl

Sandbox only. The sandbox_key_grant the portal answered when the key was taken there: MasterDB's signed statement of the key and its party, which holds no secret. The sandbox does not know a key taken in the portal until a request carries its grant: the first signed request with it creates the matching party in the sandbox and registers the key there, and is then verified like any other. Send it on every sandbox request: without it the first request with a new key is refused 401 key_unknown. A key production has revoked stays refused with its grant. Production ignores the header.

Responses

Response samples

Content type
application/json
{
  • "business_uuid": "0b7d6c3e-2f4a-4c1b-9d8e-7f6a5b4c3d2e",
  • "cert_id": "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
  • "certificate_status": "active",
  • "ai_policy_version": 3,
  • "ai_policy_live_from": "2026-09-15T10:00:00.000Z",
  • "ai_policy_record_id": "aip_abcdefghijklmnopqrstuv",
  • "next_ai_policy_version": 4
}

Analytics

Your own figures.

Read your daily figures

Your business's own figures per day, per country and per AI group (one name per group) — searches that returned your records, fetches, ad renders, clicks and spend — as at the end of the last complete hour. Never an impression figure MasterDB cannot know, never share of showings.

Authorizations:
mdbRequestSignature
query Parameters
from
string
Example: from=2026-10-01T00:00:00Z

Start of the window, inclusive (RFC 3339 UTC or a date).

to
string
Example: to=2026-10-02T00:00:00Z

End of the window, exclusive (RFC 3339 UTC or a date).

Responses

Response samples

Content type
application/json
{
  • "as_at": "2026-10-01T14:00:00.000Z",
  • "days": [
    ]
}

See which AI groups retrieved your records

The AI groups that retrieved your business's records over the last 30 days, by name, with counts, country as the axis. It is what the business-side block decision is made from.

Authorizations:
mdbRequestSignature
query Parameters
country
string (Country) ^[A-Z]{2}$
Example: country=US

ISO 3166-1 alpha-2, from the platform vocabulary.

Responses

Response samples

Content type
application/json
{
  • "as_at": "2026-10-01T14:00:00.000Z",
  • "window_days": 30,
  • "groups": [
    ]
}