{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/past-dev/json-schema/past-dev-ingest-estimate-schema.json",
  "title": "IngestEstimate",
  "x-generated": "2026-10-31",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/past-dev-openapi.json#/components/schemas/IngestEstimate",
  "type": "object",
  "required": [
    "files",
    "dataPoints",
    "bytes",
    "credits",
    "batches",
    "points",
    "pointsOmitted",
    "balance",
    "fits",
    "fitsFirst",
    "metered",
    "timeZone"
  ],
  "additionalProperties": false,
  "properties": {
    "files": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/IngestEstimateFileResult"
      }
    },
    "dataPoints": {
      "type": "integer"
    },
    "bytes": {
      "type": "integer"
    },
    "credits": {
      "type": [
        "number",
        "null"
      ],
      "description": "Null when nothing is metered."
    },
    "batches": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/IngestEstimateBatch"
      }
    },
    "points": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/IngestEstimatePoint"
      }
    },
    "pointsOmitted": {
      "type": "integer",
      "description": "The points past the listing cap."
    },
    "balance": {
      "oneOf": [
        {
          "$ref": "#/$defs/IngestEstimateBalance"
        },
        {
          "type": "null"
        }
      ]
    },
    "fits": {
      "type": "boolean",
      "description": "Whether the whole import fits what is left to spend."
    },
    "fitsFirst": {
      "type": "integer",
      "description": "How many points, in time order, do fit."
    },
    "metered": {
      "type": "boolean",
      "description": "False on a deployment with no plan."
    },
    "timeZone": {
      "type": "string"
    }
  },
  "$defs": {
    "IngestEstimateBalance": {
      "type": "object",
      "required": [
        "left",
        "resetsAt",
        "projectCapLeft",
        "ingestionCapReached"
      ],
      "additionalProperties": false,
      "properties": {
        "left": {
          "type": [
            "number",
            "null"
          ],
          "description": "The credits the account may still draw. Null with no plan."
        },
        "resetsAt": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time",
          "description": "Null where the credits never reset."
        },
        "projectCapLeft": {
          "type": [
            "number",
            "null"
          ],
          "description": "This project's credit cap left. Null with no credit cap."
        },
        "ingestionCapReached": {
          "type": "boolean"
        }
      }
    },
    "IngestEstimateBatch": {
      "type": "object",
      "required": [
        "index",
        "from",
        "to",
        "points",
        "bytes",
        "credits",
        "idempotencyKey"
      ],
      "additionalProperties": false,
      "properties": {
        "index": {
          "type": "integer"
        },
        "from": {
          "type": "integer",
          "description": "The first point's position in the cut."
        },
        "to": {
          "type": "integer",
          "description": "The last point's position in the cut."
        },
        "points": {
          "type": "integer",
          "description": "At most 500."
        },
        "bytes": {
          "type": "integer",
          "description": "At most 8 MiB of content."
        },
        "credits": {
          "type": [
            "number",
            "null"
          ]
        },
        "idempotencyKey": {
          "type": "string",
          "description": "Send the batch with this key so a retry never doubles a point."
        }
      }
    },
    "IngestEstimateFileResult": {
      "type": "object",
      "required": [
        "path",
        "kind",
        "detectedBy",
        "points",
        "bytes",
        "credits",
        "skipped"
      ],
      "additionalProperties": false,
      "properties": {
        "path": {
          "type": "string"
        },
        "kind": {
          "type": [
            "string",
            "null"
          ],
          "description": "The kind the file was read as. Null for a skipped file."
        },
        "detectedBy": {
          "type": [
            "string",
            "null"
          ],
          "description": "The rule that decided the kind, for example extension .md."
        },
        "points": {
          "type": "integer"
        },
        "bytes": {
          "type": "integer"
        },
        "credits": {
          "type": [
            "number",
            "null"
          ]
        },
        "skipped": {
          "type": [
            "string",
            "null"
          ],
          "enum": [
            "empty",
            "unreadable",
            "too-large",
            "kind-mismatch",
            null
          ],
          "description": "Why the file was left out, when it was."
        }
      }
    },
    "IngestEstimatePoint": {
      "type": "object",
      "required": [
        "id",
        "kind",
        "path",
        "label",
        "timestamp",
        "identity",
        "audience",
        "bytes",
        "credits",
        "preview"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "type": [
            "string",
            "null"
          ],
          "description": "The stable source id the point will be sent under."
        },
        "kind": {
          "type": [
            "string",
            "null"
          ]
        },
        "path": {
          "type": [
            "string",
            "null"
          ],
          "description": "The file the point came from."
        },
        "label": {
          "type": "string"
        },
        "timestamp": {
          "type": [
            "string",
            "null"
          ],
          "format": "date-time"
        },
        "identity": {
          "type": [
            "string",
            "null"
          ]
        },
        "audience": {
          "type": [
            "string",
            "null"
          ]
        },
        "bytes": {
          "type": "integer"
        },
        "credits": {
          "type": [
            "number",
            "null"
          ]
        },
        "preview": {
          "type": "string",
          "description": "The first 160 characters of the content."
        },
        "content": {
          "type": [
            "string",
            "null"
          ],
          "description": "With points full only: the content to send. Null otherwise."
        },
        "metadata": {
          "type": [
            "object",
            "null"
          ],
          "description": "With points full only: the metadata the cut recorded. Null otherwise."
        }
      }
    }
  }
}