{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/aspern-org/json-schema/aspern-org-counterparty-check-schema.json",
  "title": "CounterpartyCheck",
  "description": "One address before you deal with it. Added 2026-09-22.",
  "x-generated": "2026-11-01",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/aspern-org-openapi.json#/components/schemas/CounterpartyCheck",
  "type": "object",
  "required": [
    "data",
    "meta",
    "warnings"
  ],
  "properties": {
    "data": {
      "type": "object",
      "required": [
        "address",
        "format",
        "asOf",
        "observations",
        "identity",
        "services",
        "dealings",
        "x402",
        "acp",
        "mech",
        "masumi",
        "limits"
      ],
      "properties": {
        "address": {
          "type": "string",
          "description": "EVM lower-cased; any other kind as given, since base58 and bech32 are not case-free in the same way."
        },
        "parts": {
          "type": "object",
          "additionalProperties": true,
          "description": "Which parts of the check answered inside their budget: `complete`, `ran` and `failed`. A part in `failed` is MISSING from this answer, not absent for the address: read its fields as unknown. If the record itself does not answer, the route returns 503 with Retry-After instead."
        },
        "alsoHere": {
          "type": [
            "object",
            "null"
          ],
          "description": "The same address on the CAPITAL side of this platform — a vault we read, or an operator who runs books — with the path to that check. A match on the address and never an identification of the party: the one paying on a rail and the one running a book are not asserted to be the same people."
        },
        "format": {
          "type": "object",
          "required": [
            "kind",
            "coverage",
            "says"
          ],
          "description": "What kind of address this is and what we read for it.",
          "properties": {
            "kind": {
              "enum": [
                "evm",
                "cardano",
                "cardano-stake",
                "cardano-byron",
                "solana",
                "bitcoin",
                "cosmos",
                "unknown"
              ]
            },
            "chain": {
              "type": [
                "string",
                "null"
              ]
            },
            "network": {
              "enum": [
                "mainnet",
                "testnet",
                null
              ]
            },
            "coverage": {
              "enum": [
                "rails",
                "identity-only"
              ],
              "description": "`rails`: payment rails are read for it. `identity-only`: registrations only, and every payment section is null."
            },
            "says": {
              "type": "string"
            }
          }
        },
        "asOf": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "When the counterparty job last rebuilt the record this answer is read from."
        },
        "observations": {
          "type": "array",
          "description": "One line per dimension, in the order a buyer would ask. Tones colour a reading; they are not a verdict and are never added up.",
          "items": {
            "type": "object",
            "required": [
              "key",
              "tone",
              "evidence",
              "says"
            ],
            "properties": {
              "key": {
                "enum": [
                  "never-paid",
                  "independent-payers",
                  "two-way",
                  "all-two-way",
                  "concentrated",
                  "acp-delivery",
                  "service-serving",
                  "service-silent",
                  "unregistered",
                  "no-rail-read",
                  "dormant",
                  "recent",
                  "new-counterparties",
                  "concentrating"
                ]
              },
              "tone": {
                "enum": [
                  "good",
                  "warn",
                  "bad",
                  "neutral"
                ]
              },
              "evidence": {
                "enum": [
                  "observed",
                  "declared"
                ]
              },
              "says": {
                "type": "string"
              }
            }
          }
        },
        "identity": {
          "type": "object",
          "description": "What it says it is: registrations held by this address in the registry that can hold it. A claim, listed apart from behaviour.",
          "properties": {
            "evidence": {
              "const": "declared"
            },
            "registry": {
              "enum": [
                "erc8004",
                "solana",
                null
              ],
              "description": "Null where no registry we read can name this address as an owner (Cardano)."
            },
            "registrations": {
              "type": "integer",
              "minimum": 0,
              "x-unit": "count"
            },
            "chains": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "names": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "firstRegistered": {
              "type": [
                "string",
                "null"
              ],
              "format": "date-time"
            },
            "crossRegistryClaims": {
              "type": "object",
              "additionalProperties": {
                "type": "integer"
              },
              "description": "Claims its cards make about other registries, by whether we found them."
            }
          }
        },
        "services": {
          "type": [
            "object",
            "null"
          ],
          "properties": {
            "evidence": {
              "const": "observed"
            },
            "declared": {
              "type": "integer",
              "minimum": 0,
              "description": "Callable services (MCP, A2A) its registrations declare."
            },
            "serving": {
              "type": "integer",
              "minimum": 0,
              "description": "Of those, how many answered our probe on its latest day."
            },
            "endpoints": {
              "type": "array",
              "description": "Every endpoint the address declares, at most 20. NOT the same population as `declared`/`serving` above, which count only the protocols we probe — so a count of 1 beside a list of 2 is those two populations, not an error. These are what makes a chain walkable: without the url there is nothing to hand /v1/service, and nothing to give /v1/preflight as `resource` — its sharpest check, because a catalogue entry carries the seller’s own price and own payee.",
              "items": {
                "type": "object",
                "properties": {
                  "declared": {
                    "type": "string",
                    "description": "The card’s own word for the service. A label a reader sees should be its author’s."
                  },
                  "protocol": {
                    "type": "string",
                    "description": "mcp | a2a | x402 | oasf | web | wallet | social | other."
                  },
                  "url": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Where the owner SAYS their service is. A claim, never our verification of it."
                  },
                  "host": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "priceUsd": {
                    "type": [
                      "number",
                      "null"
                    ],
                    "description": "A price the card states. Null is unpriced, which is not free.",
                    "x-unit": "usd"
                  },
                  "declaredTools": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "How many tool names the card lists. Zero is “named none”, not “has none”."
                  },
                  "evidence": {
                    "const": "declared"
                  },
                  "probeable": {
                    "type": "boolean",
                    "description": "True where this is a protocol we call (mcp, a2a). False for a web page, a wallet or a social handle, which are listed and never called. It exists so one null does not mean two things: `lastProbe: null` with this true means we have not looked yet, and with this false means we never look at this kind. It also reconciles `declared`/`serving` — which count only the probeable protocols — with a longer list."
                  },
                  "lastProbe": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "description": "Our reading of whether it answered, on the day stated. Null is never “it is down”: read it with `probeable`, which says whether looking was even possible.",
                    "properties": {
                      "evidence": {
                        "const": "observed"
                      },
                      "day": {
                        "type": "string",
                        "format": "date"
                      },
                      "outcome": {
                        "type": "string",
                        "description": "mcp: serving | gated | no-handshake | error | unreachable. a2a: serving | gated | not-a-card | unreachable."
                      },
                      "name": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "What the server called ITSELF when it answered, which need not match `declared`."
                      },
                      "toolsAnswered": {
                        "type": "integer",
                        "minimum": 0,
                        "description": "How many it actually listed, against `declaredTools` which is what the card claims."
                      },
                      "latencyMs": {
                        "type": [
                          "integer",
                          "null"
                        ],
                        "x-unit": "seconds"
                      }
                    }
                  }
                }
              }
            },
            "says": {
              "type": "string"
            }
          }
        },
        "dealings": {
          "type": [
            "object",
            "null"
          ],
          "description": "Null where no payment rail is read for this kind of address.",
          "properties": {
            "evidence": {
              "const": "observed"
            },
            "rails": {
              "type": "array",
              "items": {
                "enum": [
                  "x402",
                  "acp",
                  "mech",
                  "masumi"
                ]
              }
            },
            "chains": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "The networks those dealings settled on. A rail mostly implies one; x402 spans five."
            },
            "total": {
              "type": "integer",
              "minimum": 0,
              "description": "x402 sales received plus ACP jobs taken.",
              "x-unit": "count"
            },
            "counterparties": {
              "type": "integer",
              "minimum": 0
            },
            "independent": {
              "type": "integer",
              "minimum": 0,
              "description": "Counterparties it has never paid back."
            },
            "twoWay": {
              "type": "object",
              "properties": {
                "counterparties": {
                  "type": "integer",
                  "minimum": 0
                },
                "dealings": {
                  "type": "integer",
                  "minimum": 0
                },
                "usd": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "x-unit": "usd"
                }
              }
            },
            "largestShare": {
              "type": [
                "number",
                "null"
              ],
              "minimum": 0,
              "maximum": 1,
              "description": "The largest single counterparty’s share of the dealings, as a decimal fraction.",
              "x-unit": "decimal-fraction"
            },
            "suppliers": {
              "type": "integer",
              "minimum": 0,
              "description": "Distinct parties this agent has PAID. Zero means it has paid nobody on a rail we read, never that it depends on nobody."
            },
            "largestSupplierShare": {
              "type": [
                "number",
                "null"
              ],
              "minimum": 0,
              "maximum": 1,
              "description": "The largest supplier’s share of those payments. Null below three suppliers, where the share could only be a half or a whole. The other direction from `largestShare`, and the one that says whether the agent itself would still be here if one party stopped.",
              "x-unit": "decimal-fraction"
            },
            "spent": {
              "type": [
                "number",
                "null"
              ],
              "description": "The priced part of what it paid out. Null where nothing was priced, never 0."
            },
            "recent": {
              "type": "object",
              "description": "The same record over the last 7, 30 and 90 days. Every other figure here is all-time, and an agent paid well a year ago and nothing since is a different proposition from one paid yesterday.",
              "properties": {
                "dealings7": {
                  "type": "integer",
                  "minimum": 0
                },
                "dealings30": {
                  "type": "integer",
                  "minimum": 0
                },
                "dealings90": {
                  "type": "integer",
                  "minimum": 0
                },
                "counterparties90": {
                  "type": "integer",
                  "minimum": 0
                },
                "newCounterparties90": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Counterparties whose FIRST dealing with it falls inside 90 days: winning custom rather than keeping it."
                },
                "largestShare90": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "minimum": 0,
                  "maximum": 1,
                  "description": "Concentration over 90 days, against `largestShare` over all time."
                }
              }
            },
            "usd": {
              "type": [
                "number",
                "null"
              ],
              "description": "The priced part of the dealings. Null where nothing was priced, never 0.",
              "x-unit": "usd"
            },
            "firstPaid": {
              "type": [
                "string",
                "null"
              ],
              "format": "date-time"
            },
            "lastPaid": {
              "type": [
                "string",
                "null"
              ],
              "format": "date-time"
            }
          }
        },
        "independence": {
          "type": [
            "object",
            "null"
          ],
          "description": "WHETHER THIS ADDRESS’S PAYERS ARE INDEPENDENT OF EACH OTHER. `dealings.independent` counts payers that never paid it back, and the caveat on this endpoint has always said that is not proof they are different parties. This measures it: payers of this address that share an OBSCURE third party with another of its payers. Obscure is load-bearing — a party paid by between two and ten addresses in all counts, a hub paid by more does not, because two agents both paying a hub have shown only that the hub is popular. The counts are free; `groups`, which names WHICH payers and through WHAT, needs `independence.test` and is null without it, with `capability` saying so. Null for an address we have not tested.",
          "properties": {
            "evidence": {
              "type": "string",
              "enum": [
                "observed"
              ]
            },
            "payers": {
              "type": "integer",
              "minimum": 0,
              "description": "Distinct parties that paid it, counted from the same edges the linking uses rather than from the sale-filtered dealings above. Two populations under one name is how a denominator drifts from its numerator.",
              "x-unit": "count"
            },
            "linked": {
              "type": "integer",
              "minimum": 0,
              "description": "Of those, how many share an obscure party with another of them. Zero means no pair of its payers shares one on the rails we read, which is not proof they are unrelated."
            },
            "viaParties": {
              "type": "integer",
              "minimum": 0,
              "description": "How many distinct obscure parties do the linking."
            },
            "largestGroup": {
              "type": "integer",
              "minimum": 0,
              "description": "The most payers of this address found paying one obscure party. Two is a coincidence; nine is a shape."
            },
            "groups": {
              "type": [
                "array",
                "null"
              ],
              "description": "Paid. Each obscure party and the payers of this address that pay it, largest group first, at most a hundred.",
              "items": {
                "type": "object",
                "properties": {
                  "via": {
                    "type": "string",
                    "description": "The party they have in common."
                  },
                  "payers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "count": {
                    "type": "integer",
                    "minimum": 2,
                    "x-unit": "count"
                  }
                }
              }
            },
            "capability": {
              "type": [
                "string",
                "null"
              ],
              "description": "Set only where `groups` is withheld: the capability that would answer it."
            },
            "withheld": {
              "type": [
                "string",
                "null"
              ],
              "description": "What is not in this answer and why, so a null field is never mistaken for an empty one."
            },
            "asOf": {
              "type": "string",
              "format": "date-time"
            },
            "says": {
              "type": "string",
              "description": "That this is evidence of a link and never proof of one operator. Quote it with the numbers."
            }
          }
        },
        "restsOn": {
          "type": [
            "object",
            "null"
          ],
          "description": "Every party this address has PAID on a rail we read. NOT the mirror of `dealings`: a dealing is a sale and needs a seller on the other end, while a payment out counts whoever receives it, because an agent paying an address that publishes no catalogue still cannot work if that address stops. Null where this kind of address is not read on any rail.",
          "properties": {
            "evidence": {
              "type": "string",
              "enum": [
                "observed"
              ]
            },
            "suppliers": {
              "type": "integer",
              "minimum": 0,
              "description": "Distinct parties it has paid. Zero means it has paid nobody on a rail we read, never that it depends on nobody."
            },
            "payments": {
              "type": "integer",
              "minimum": 0,
              "x-unit": "count"
            },
            "spentUsd": {
              "type": [
                "number",
                "null"
              ],
              "description": "The priced part of what it paid out. Null where nothing was priced, never 0.",
              "x-unit": "usd"
            },
            "largestShare": {
              "type": [
                "number",
                "null"
              ],
              "minimum": 0,
              "maximum": 1,
              "description": "The largest supplier’s share of those payments. Null below three suppliers, where the share can only be a half or a whole and would read as concentration rather than as a thin record.",
              "x-unit": "decimal-fraction"
            },
            "recent": {
              "type": "object",
              "description": "The same two inside ninety days. A dependence that ended last quarter is a different proposition from one that is current.",
              "properties": {
                "suppliers90": {
                  "type": "integer",
                  "minimum": 0
                },
                "largestShare90": {
                  "type": [
                    "number",
                    "null"
                  ],
                  "minimum": 0,
                  "maximum": 1,
                  "description": "Taken over the ninety-day suppliers, not over all of them."
                }
              }
            },
            "says": {
              "type": "string",
              "description": "What a recipient here has and has not been shown to be."
            }
          }
        },
        "x402": {
          "type": [
            "object",
            "null"
          ],
          "properties": {
            "sales": {
              "type": "integer",
              "minimum": 0
            },
            "payers": {
              "type": "integer",
              "minimum": 0,
              "x-unit": "count"
            }
          }
        },
        "acp": {
          "type": [
            "object",
            "null"
          ],
          "properties": {
            "jobs": {
              "type": "integer",
              "minimum": 0,
              "x-unit": "count"
            },
            "completed": {
              "type": "integer",
              "minimum": 0
            },
            "rejected": {
              "type": "integer",
              "minimum": 0
            },
            "expired": {
              "type": "integer",
              "minimum": 0
            },
            "clients": {
              "type": "integer",
              "minimum": 0
            },
            "completion": {
              "type": [
                "number",
                "null"
              ],
              "minimum": 0,
              "maximum": 1,
              "description": "Completed over jobs that reached an outcome. Null with none."
            }
          }
        },
        "mech": {
          "type": [
            "object",
            "null"
          ],
          "properties": {
            "deliveries": {
              "type": "integer",
              "minimum": 0
            },
            "paidUsd": {
              "type": [
                "number",
                "null"
              ],
              "x-unit": "usd"
            }
          }
        },
        "masumi": {
          "type": [
            "object",
            "null"
          ],
          "description": "Cardano addresses only: Masumi escrows where its payment credential is the seller. `minDepositAda` IS NOT A PRICE — it is the minimum ADA a UTxO holding a token must carry, summed over those escrows. A Masumi escrow is denominated in USDM (304 of 304 sampled escrow outputs carry the token) and 29,238 escrows hold 26 distinct lovelace amounts, which is a protocol constant rather than a market. `usdm` is the figure that would be the value and it is NULL because we have not read the token quantities: unread, never zero. Until it is read, the escrow COUNT is the supportable answer about this rail.",
          "properties": {
            "escrows": {
              "type": "integer",
              "minimum": 0
            },
            "buyers": {
              "type": "integer",
              "minimum": 0
            },
            "minDepositAda": {
              "type": [
                "number",
                "null"
              ]
            },
            "held": {
              "type": "array",
              "description": "What those outputs hold, by symbol, in the asset’s own units. Quantities only: a stablecoin being worth a dollar is not the same as our holding a dated price for it, which we do not for Cardano. An empty array with `escrowsRead: 0` means unread rather than empty.",
              "items": {
                "type": "object"
              }
            },
            "escrowsRead": {
              "type": "integer",
              "minimum": 0,
              "description": "How many of them we have read the contents of. The reader walks twenty thousand transactions."
            },
            "of": {
              "type": "integer",
              "minimum": 0
            },
            "countsOutputsNotJobs": {
              "const": true,
              "description": "ALWAYS TRUE, and the most important field here. The Masumi payment contract advances a job by SPENDING its escrow output and creating a new one, so one job appears in the contract as several outputs and every count and quantity above counts outputs. Measured over 400 transactions: 160 of 319 contract outputs were new jobs and 159 continued one already there, which is 1.99x by count and 2.00x by value. Read `escrows` and `held` as CEILINGS of about double until the chains are followed."
            },
            "says": {
              "type": "string"
            }
          }
        },
        "limits": {
          "type": "string"
        }
      }
    },
    "meta": {
      "$ref": "#/$defs/Meta"
    },
    "warnings": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/Warning"
      }
    }
  },
  "$defs": {
    "Meta": {
      "type": "object",
      "required": [
        "requestId",
        "snapshotId",
        "servedAt",
        "methodologyVersion",
        "coverage"
      ],
      "properties": {
        "requestId": {
          "type": "string",
          "description": "Also the X-Request-Id header."
        },
        "environment": {
          "type": "string",
          "description": "production, staging or development. Also the X-ASPERN-Environment header and info.x-aspern-environment in the OpenAPI document, so a client can tell which contract answered."
        },
        "build": {
          "type": [
            "string",
            "null"
          ],
          "description": "The deploy that served this. Also the X-ASPERN-Build header."
        },
        "snapshotId": {
          "type": "string",
          "description": "Which state of our data answered. Two responses with the same snapshotId saw the same completed ingest runs — so a figure that differs between two surfaces under the SAME snapshot is a defect, and under different ones is a clock."
        },
        "observedAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "When the source was observed."
        },
        "computedAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "When we computed this from it."
        },
        "servedAt": {
          "type": "string",
          "format": "date-time",
          "description": "When this response was built."
        },
        "methodologyVersion": {
          "type": "string",
          "description": "What the figures mean. Changes are listed at /changelog."
        },
        "source": {
          "type": [
            "string",
            "null"
          ]
        },
        "chainId": {
          "type": [
            "integer",
            "null"
          ],
          "x-unit": "chain-id"
        },
        "blockNumber": {
          "type": [
            "integer",
            "null"
          ],
          "x-unit": "block-number"
        },
        "coverage": {
          "type": "object",
          "properties": {
            "scope": {
              "type": [
                "string",
                "null"
              ],
              "description": "What this covers and, explicitly, what it does not."
            },
            "population": {
              "type": [
                "string",
                "null"
              ],
              "description": "The population these figures were measured over, as a key you can join on rather than a sentence you have to read. Every key is declared once and resolves to a definition at /reconciliation#<key>, where the ones that narrow show every row that falls out and why. The same key appears beside the figure on the website, so an integrator and a reader are talking about one population rather than two descriptions of it. Null only when `populationAbsence` says why."
            },
            "populationAbsence": {
              "type": [
                "string",
                "null"
              ],
              "description": "Why there is no single population, where there is none. A lookup of one address measures nothing; a document carrying several rails in units that are never summed carries several populations. A null population with nothing here would be an absence you could not tell from an oversight, which is the defect this field exists to close."
            },
            "knownExclusions": {
              "type": [
                "array",
                "null"
              ],
              "items": {
                "type": "string"
              },
              "description": "THREE VALUES. A list is what this route deliberately leaves out. `[]` is a CLAIM that nothing is excluded. `null` is “we have not said”, which is our gap and must never be read as the second. It was hardcoded to `[]` on every route until 2026-09-27, so every response claimed to exclude nothing while its own `scope` sentence named exclusions."
            }
          }
        },
        "confidence": {
          "type": [
            "object",
            "null"
          ],
          "description": "Never a bare number; it names what it is a confidence in."
        },
        "freshness": {
          "anyOf": [
            {
              "type": "object",
              "required": [
                "oldestObservedAt",
                "newestObservedAt",
                "readings",
                "fields",
                "complete",
                "state",
                "newestAgeHours"
              ],
              "description": "When the readings behind this answer were taken, where they differ. A page of a hundred vaults read over four hours has no single observation time — `observedAt` is filled in only where every reading agrees, and this reports the spread otherwise.",
              "properties": {
                "oldestObservedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "newestObservedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "readings": {
                  "type": "integer",
                  "minimum": 1,
                  "description": "How many readings the range was taken over.",
                  "x-unit": "count"
                },
                "fields": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "description": "The fields it was read from, so a caller can go and check any of them directly."
                },
                "complete": {
                  "type": "boolean",
                  "description": "Whether every reading in the payload was seen. False means the range is a LOWER BOUND — the true spread is at least this wide and may be wider — because a partial walk always returns the narrower range, which would read as fresher and more uniform than the data is."
                },
                "state": {
                  "enum": [
                    "fresh",
                    "mixed",
                    "stale"
                  ],
                  "description": "`stale` when the NEWEST reading is more than 26 hours old at the moment the response was built — every reader runs at least daily, so that means a reader has stopped. `mixed` when the newest is inside that window and the OLDEST is not: parts of this answer are current and parts are not, which is the usual shape of a document joining several sources. It was summarised as `fresh` until 2026-10-10, computed from the newest reading alone, so one current field hid a catalogue two months old. A source that could not be read is not a state here: it is a check that could not run (`/v1/checks`) or an analysis whose `availability` says so, and never a zero."
                },
                "newestAgeHours": {
                  "type": "number",
                  "minimum": 0,
                  "description": "Hours between the newest reading and the moment this response was built, to one decimal.",
                  "x-unit": "hours"
                },
                "oldestAgeHours": {
                  "type": "number",
                  "minimum": 0,
                  "description": "The same for the OLDEST reading. The other end of the spread as a number, because a caller comparing two ISO strings to find out whether part of an answer is two months old will mostly not bother.",
                  "x-unit": "hours"
                }
              }
            },
            {
              "type": "object",
              "required": [
                "reason",
                "state",
                "says",
                "readings"
              ],
              "description": "No range, and which of the two reasons it is.",
              "properties": {
                "reason": {
                  "enum": [
                    "not-applicable",
                    "no-dated-field"
                  ],
                  "description": "`not-applicable` is reference material: a plan, a capability list, a schema. Nothing in it was read from anywhere at a time. `no-dated-field` means the response carries data and nothing in it names when that data was read, which is a gap in that endpoint."
                },
                "state": {
                  "enum": [
                    "not_applicable",
                    "not_measured"
                  ],
                  "description": "The reason in the vocabulary shared with `fresh`/`stale`: `not-applicable` is `not_applicable`, `no-dated-field` is `not_measured`."
                },
                "says": {
                  "type": "string",
                  "description": "The same thing in a sentence."
                },
                "readings": {
                  "const": 0
                }
              }
            }
          ]
        },
        "pagination": {
          "anyOf": [
            {
              "$ref": "#/$defs/Page"
            },
            {
              "type": "null"
            }
          ]
        }
      }
    },
    "Page": {
      "type": "object",
      "required": [
        "total",
        "limit",
        "offset",
        "hasMore"
      ],
      "properties": {
        "total": {
          "type": "integer",
          "minimum": 0,
          "description": "Rows matching the filter, not rows returned.",
          "x-unit": "count"
        },
        "limit": {
          "type": "integer",
          "minimum": 0,
          "description": "Applied page size. May be below what was asked — X-Page-Limit says so when it is.",
          "x-unit": "count"
        },
        "offset": {
          "type": "integer",
          "minimum": 0,
          "x-unit": "count"
        },
        "hasMore": {
          "type": "boolean"
        },
        "nextOffset": {
          "type": [
            "integer",
            "null"
          ],
          "description": "Null on the last page.",
          "x-unit": "count"
        },
        "orderedBy": {
          "type": "string",
          "description": "The sort, including its tie-breaker. The order is total, so paging cannot show a row twice or skip one."
        }
      }
    },
    "Warning": {
      "type": "object",
      "required": [
        "code",
        "message"
      ],
      "properties": {
        "code": {
          "type": "string"
        },
        "message": {
          "type": "string"
        }
      }
    }
  }
}