---
title: "Cut and price an import"
method: POST
path: "/api/v1/ingest/estimate"
tags: ["debugging"]
---

# Cut and price an import

`POST /api/v1/ingest/estimate`

## Request

- Base URL: `https://api.past.dev`
- URL: `https://api.past.dev/api/v1/ingest/estimate`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer

Cut files into data points, batch them and price them against what is left to spend. Writes nothing, spends nothing, and leaves no row in the request log.

## Request body

- IngestEstimateRequest
  - `files` IngestEstimateFile[]: The files to cut. Send files or items, never both and never neither.
    - `path` string, required: The path inside the import. Its extension helps detection.
    - `content` string, required: The file as text. Extract PDF or office text yourself first.
    - `kind` 'email' | 'chat' | 'transcript' | 'table' | 'records' | 'code' | 'documentation' | 'notes': Read the file as this kind instead of detecting it.
  - `items` IngestItem[]: Data points you cut yourself, batched and priced as given.
    - `content` string, required: Raw text. Empty or whitespace-only content is refused.
    - `label` string: Optional short title for the data point, stored as its own field and returned as label on recall sources. Omitted on a re-send, the stored label stays.
    - `id` string: Stable source id. When omitted, the lowercase SHA-256 of content is used.
    - `timestamp` string, date-time: When the content occurred. Stored at microsecond precision.
    - `metadata` union: Optional caller JSON stored with the source.
      - object
      - string
      - number
      - boolean
    - `audience` string: Audience slug. Omit it or send project for project-visible memory.
    - `identity` string: Customer id for the author. Its first ingest appearance creates the directory record.
  - `timeZone` string: IANA zone reading the times a file writes without one. UTC when omitted.
  - `points` 'none' | 'summary' | 'full': How much of each point the answer lists.

## Response `200`

The cut, the batches to send it in, and what it costs.

- IngestEstimate
  - `files` IngestEstimateFileResult[], required
    - `path` string, required
    - `kind` string, nullable, required: The kind the file was read as. Null for a skipped file.
    - `detectedBy` string, nullable, required: The rule that decided the kind, for example extension .md.
    - `points` integer, required
    - `bytes` integer, required
    - `credits` number, nullable, required
    - `skipped` 'empty' | 'unreadable' | 'too-large' | 'kind-mismatch' | 'null', nullable, required: Why the file was left out, when it was.
  - `dataPoints` integer, required
  - `bytes` integer, required
  - `credits` number, nullable, required: Null when nothing is metered.
  - `batches` IngestEstimateBatch[], required
    - `index` integer, required
    - `from` integer, required: The first point's position in the cut.
    - `to` integer, required: The last point's position in the cut.
    - `points` integer, required: At most 500.
    - `bytes` integer, required: At most 8 MiB of content.
    - `credits` number, nullable, required
    - `idempotencyKey` string, required: Send the batch with this key so a retry never doubles a point.
  - `points` IngestEstimatePoint[], required
    - `id` string, nullable, required: The stable source id the point will be sent under.
    - `kind` string, nullable, required
    - `path` string, nullable, required: The file the point came from.
    - `label` string, required
    - `timestamp` string, date-time, nullable, required
    - `identity` string, nullable, required
    - `audience` string, nullable, required
    - `bytes` integer, required
    - `credits` number, nullable, required
    - `preview` string, required: The first 160 characters of the content.
    - `content` string, nullable: With points full only: the content to send. Null otherwise.
    - `metadata` object, nullable: With points full only: the metadata the cut recorded. Null otherwise.
  - `pointsOmitted` integer, required: The points past the listing cap.
  - `balance` IngestEstimateBalance, required
    - `left` number, nullable, required: The credits the account may still draw. Null with no plan.
    - `resetsAt` string, date-time, nullable, required: Null where the credits never reset.
    - `projectCapLeft` number, nullable, required: This project's credit cap left. Null with no credit cap.
    - `ingestionCapReached` boolean, required
  - `fits` boolean, required: Whether the whole import fits what is left to spend.
  - `fitsFirst` integer, required: How many points, in time order, do fit.
  - `metered` boolean, required: False on a deployment with no plan.
  - `timeZone` string, required

## Other responses

- `400`: The request is malformed or violates a field constraint. Match behavior on the response code field.
- `401`: missing-api-key: no bearer. malformed-api-key: the header or the key has the wrong shape, or an agent token was sent to a route that accepts keys only. unauthorized: the key is unknown, expired, revoked, or of the kind this route refuses, or the agent token is invalid or expired.
- `403`: project-archived: the project of the key, or the project an agent token names, is archived. Unarchive it in the console to resume. insufficient-scope: the agent token does not carry the scope of the route.
- `429`: The plan's requests per minute are exceeded. This refusal carries no body.
- `default`: Any other failure uses the same JSON error envelope.

---

[API](https://skmtc.dev/past/apis/past-dev-memory-api.md) · [All operations](https://skmtc.dev/past/apis/past-dev-memory-api/llms.txt) · [OpenAPI document](https://skmtc.dev/past/apis/past-dev-memory-api/revisions/3ddccc19f0eb?raw)
