Demiton · Schema

email_issue contract v1

The Email issue register contract, version 1. JSON Schema (draft 2020-12); x-demiton-* keywords carry Demiton's own meaning and standard validators ignore them.

CompanyConstructionCivil EngineeringProject ManagementComplianceMCPArtificial IntelligenceOpen Contracting

Properties

Name Type Description
kind string What kind of issue it is, chosen by the person in the panel. Documents the vocabulary for the panel and the validators; the write path refuses an unknown value (email_issue_kinds.validate_kind), becau
clock object The notice clock computed in code at raise time. Code, never the model, and P9 arms a window from `applies` alone.
chosen object What the person actually picked, which is what the rest of the payload reflects.
emails array Every email stored as this issue's evidence, the raised one first.
sender string The From address of the raised email.
guessed object What the panel pre-selected, kept so the guess's accuracy can be measured again from production rows.
project string The job this issue was raised against, by name. The fact also carries the project as its coordinate, which is what the window engine reads.
raisers array The Demiton user ids who raised this issue; more than one when two people raised the same message.
subject string The subject line of the raised email.
currency string ISO 4217 code of `estimate`. Present exactly when `estimate` is.
estimate number the raiser's estimate of what this costs the job if nobody acts, in `currency`. Never `amount`: that key is in the claim-window verdict's exposure keys and would reach the Baseline.
message_id string The raised email's internetMessageId. With the org, the kind and the project it is the dedupe key.
estimate_at string when the estimate was raised, UTC. The pilot window filters on this.
estimate_by integer the Demiton user id whose estimate this is: the first raiser's.
received_at string The raised email's own Date header, ISO 8601. The fact's occurred_at and every window deadline are counted from this, never from the day someone noticed.
sender_domain string The sender's domain, as used to match the job.
View JSON Schema on GitHub

JSON Schema

demiton-io-email_issue-v1-schema.json Raw ↑
{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://docs.demiton.io/registers/email_issue/v1.json",
  "title": "email_issue contract v1",
  "type": "object",
  "required": [
    "clock",
    "emails",
    "kind",
    "message_id",
    "project",
    "raisers",
    "received_at",
    "sender",
    "subject"
  ],
  "properties": {
    "kind": {
      "type": "string",
      "description": "What kind of issue it is, chosen by the person in the panel. Documents the vocabulary for the panel and the validators; the write path refuses an unknown value (email_issue_kinds.validate_kind), because the fact gate checks presence and type only and enforces no enum anywhere.",
      "enum": [
        "extra_work",
        "delay",
        "defect",
        "dispute",
        "over_budget",
        "compliance",
        "other"
      ],
      "x-demiton-requiredness": "required"
    },
    "clock": {
      "type": "object",
      "description": "The notice clock computed in code at raise time. Code, never the model, and P9 arms a window from `applies` alone.",
      "properties": {
        "days": {
          "type": "integer",
          "description": "The period in days, as the contract states it.",
          "x-demiton-requiredness": "optional"
        },
        "clause": {
          "type": "string",
          "description": "The contract clause the period comes from.",
          "x-demiton-requiredness": "optional"
        },
        "applies": {
          "type": "boolean",
          "description": "True only when the kind can start a clock, the sender is on the principal's side, and contract_terms states the period.",
          "x-demiton-requiredness": "required"
        },
        "deadline": {
          "type": "string",
          "description": "The date the notice is due, counted from received_at.",
          "x-demiton-requiredness": "optional",
          "format": "date",
          "x-demiton-type": "date"
        }
      },
      "x-demiton-requiredness": "required"
    },
    "chosen": {
      "type": "object",
      "description": "What the person actually picked, which is what the rest of the payload reflects.",
      "properties": {
        "job": {
          "type": "string",
          "description": "The job as raised, by name.",
          "x-demiton-requiredness": "optional"
        },
        "kind": {
          "type": "string",
          "description": "The kind as raised.",
          "x-demiton-requiredness": "optional"
        }
      },
      "x-demiton-requiredness": "optional"
    },
    "emails": {
      "type": "array",
      "description": "Every email stored as this issue's evidence, the raised one first.",
      "items": {
        "type": "object",
        "properties": {
          "blob": {
            "type": "string",
            "description": "The org-uploads key of the stored .eml (org_<id>/evidence/email_issue/<sha256>.eml).",
            "x-demiton-requiredness": "required"
          },
          "subject": {
            "type": "string",
            "description": "That email's subject line.",
            "x-demiton-requiredness": "required"
          },
          "received_at": {
            "type": "string",
            "description": "That email's Date header, ISO 8601.",
            "x-demiton-requiredness": "required",
            "format": "date-time",
            "x-demiton-type": "datetime"
          }
        }
      },
      "x-demiton-requiredness": "required"
    },
    "sender": {
      "type": "string",
      "description": "The From address of the raised email.",
      "x-demiton-requiredness": "required"
    },
    "guessed": {
      "type": "object",
      "description": "What the panel pre-selected, kept so the guess's accuracy can be measured again from production rows.",
      "properties": {
        "job": {
          "type": "string",
          "description": "The guessed job, by name.",
          "x-demiton-requiredness": "optional"
        },
        "kind": {
          "type": "string",
          "description": "The guessed kind, or null when nothing was guessed.",
          "x-demiton-requiredness": "optional"
        }
      },
      "x-demiton-requiredness": "optional"
    },
    "project": {
      "type": "string",
      "description": "The job this issue was raised against, by name. The fact also carries the project as its coordinate, which is what the window engine reads.",
      "x-demiton-requiredness": "required"
    },
    "raisers": {
      "type": "array",
      "description": "The Demiton user ids who raised this issue; more than one when two people raised the same message.",
      "items": {
        "type": "integer"
      },
      "x-demiton-requiredness": "required"
    },
    "subject": {
      "type": "string",
      "description": "The subject line of the raised email.",
      "x-demiton-requiredness": "required"
    },
    "currency": {
      "type": "string",
      "description": "ISO 4217 code of `estimate`. Present exactly when `estimate` is.",
      "x-demiton-requiredness": "optional"
    },
    "estimate": {
      "type": "number",
      "description": "the raiser's estimate of what this costs the job if nobody acts, in `currency`. Never `amount`: that key is in the claim-window verdict's exposure keys and would reach the Baseline.",
      "x-demiton-requiredness": "optional"
    },
    "message_id": {
      "type": "string",
      "description": "The raised email's internetMessageId. With the org, the kind and the project it is the dedupe key.",
      "x-demiton-requiredness": "required"
    },
    "estimate_at": {
      "type": "string",
      "description": "when the estimate was raised, UTC. The pilot window filters on this.",
      "x-demiton-requiredness": "optional",
      "format": "date-time",
      "x-demiton-type": "datetime"
    },
    "estimate_by": {
      "type": "integer",
      "description": "the Demiton user id whose estimate this is: the first raiser's.",
      "x-demiton-requiredness": "optional"
    },
    "received_at": {
      "type": "string",
      "description": "The raised email's own Date header, ISO 8601. The fact's occurred_at and every window deadline are counted from this, never from the day someone noticed.",
      "x-demiton-requiredness": "required",
      "format": "date-time",
      "x-demiton-type": "datetime"
    },
    "sender_domain": {
      "type": "string",
      "description": "The sender's domain, as used to match the job.",
      "x-demiton-requiredness": "optional"
    }
  },
  "x-demiton-register-type": "email_issue",
  "x-demiton-contract-version": "1.1.0",
  "x-demiton-store": "tenant",
  "x-demiton-axes": [
    {
      "axis": "project",
      "requirement": "required",
      "role": "subject"
    }
  ],
  "x-demiton-measures": [],
  "x-demiton-provenance": {
    "standards": []
  },
  "description": "The Email issue register contract, version 1. JSON Schema (draft 2020-12); x-demiton-* keywords carry Demiton's own meaning and standard validators ignore them.",
  "x-demiton-contract-url": "https://docs.demiton.io/registers/email_issue/",
  "x-demiton-register-catalog": "https://docs.demiton.io/concepts/register-catalog"
}

Work with this as data

Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for schemas

4 MCP tools reach this
  • find_json_schemasBrowse and filter every JSON Schema in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/demiton-io-email_issue-v1"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.