# Results and Artifacts

Results are how your system retrieves processed data from Tediware. You first learn that processing has completed through a notification that carries a `resultId`: a webhook call if the partner uses webhooks, or a feed entry if it is poll-based. Your system then uses that ID to fetch the result and download the artifacts (the actual EDI or JSON files). You can also list results by trace GUID to see every step in a processing run.

## List Results

```
GET /platform/results
```

Returns a paginated list of results for your organization, ordered by most recent first.

Query parameters:

- `trace`: filter by trace GUID to see all results from a single processing run
- `node`: filter by node name or node ID to see results from a specific step. Names match case-insensitively within your organization
- `status`: `success` or `error`
- `limit`: number of results per page (default 50, maximum 100)
- `cursor`: pagination cursor from a previous response
- `compact`: `true` to return each result as `id`, `traceGuid`, `createdAt`, `nodeName`, `status`, `partnerKey` and `errorMessage`, with `errorMessage` cut to 200 characters. Use it to scan or count results; get one result by id for its `detail`

The response includes a `results` array and a `pagination` object:

```json
{
  "results": [
    {
      "id": "4c2021f8-8310-4628-80f9-b578d4d68e11",
      "traceGuid": "5ab72145-4a4b-40f6-95de-e2579f163f79",
      "createdAt": "2026-03-30T14:22:33.260Z",
      "updatedAt": "2026-03-30T14:22:33.260Z",
      "nodeName": "Mapping",
      "nodeId": "3e5c9017-aaaa-bbbb-cccc-ddddeeeeffff",
      "status": "success",
      "detail": {
        "direction": "outbound",
        "partner": { "key": "ACME_FOODS" }
      }
    }
  ],
  "pagination": {
    "hasMore": true,
    "nextCursor": "MjAyNi0wMy0zMFQxNDoyMjozMy4yNjAwMDBafDRjMjAyMWY4..."
  }
}
```

`status` is `"error"` when the step recorded a failure and `"success"` otherwise. A mapping that was delivered flagged is a `"success"` carrying `detail.mappingFailed: true`: the document went out, and the flag is a separate axis from the outcome.

`nodeId` is there so the `node` filter is usable from a row you already have. The name is what every view displays, so the filter accepts either.

Filtering by `status` reads rows in page order and sifts them, because result metadata is encrypted and the flag cannot be a database predicate. A page therefore scans a bounded number of rows and hands back a cursor at the last row it looked at, which keeps a filter that matches nothing for a long stretch from turning into a full scan. Page it the same way as any other list.

Results use cursor-based pagination. When `hasMore` is `true`, pass the `nextCursor` value as the `cursor` parameter in your next request to retrieve the following page.

```bash
# First page
curl "https://tediware.com/platform/results?trace=5ab72145-4a4b-40f6-95de-e2579f163f79&limit=10" \
  -H "Authorization: Key your-api-key-here"

# Next page
curl "https://tediware.com/platform/results?trace=5ab72145-4a4b-40f6-95de-e2579f163f79&limit=10&cursor=MjAyNi0wMy0zMFQxNDoyMjozMy4yNjAwMDBafDRjMjAyMWY4..." \
  -H "Authorization: Key your-api-key-here"
```

## Get a Single Result

```
GET /platform/results/:id
```

Returns the full detail for a single result:

```json
{
  "id": "4c2021f8-8310-4628-80f9-b578d4d68e11",
  "traceGuid": "5ab72145-4a4b-40f6-95de-e2579f163f79",
  "createdAt": "2026-03-30T14:22:33.260Z",
  "updatedAt": "2026-03-30T14:22:33.260Z",
  "nodeName": "Implementation",
  "nodeId": "3e5c9017-aaaa-bbbb-cccc-ddddeeeeffff",
  "status": "success",
  "detail": {
    "direction": "outbound",
    "partner": { "key": "ACME_FOODS" },
    "x12": {
      "sender": {
        "isa": { "qualifier": "ZZ", "id": "YOURID" }
      },
      "receiver": {
        "isa": { "qualifier": "ZZ", "id": "PARTNERID" }
      },
      "transaction": {
        "transactionSetIdentifier": "810",
        "controlNumber": 1043
      },
      "interchange": {
        "controlNumber": 1042
      },
      "functionalGroup": {
        "controlNumber": 1043
      }
    },
    "artifacts": [
      { "id": "1dc6a6fb-abcd-1234-ef56-789012345678", "usage": "input", "contentType": "application/json", "filename": "invoice-001.json" },
      { "id": "b613c64c-dcba-4321-fe65-987654321098", "usage": "output", "contentType": "application/edi-x12", "filename": "invoice-001.edi" }
    ],
    "transformations": ["mapping", "implementation validation + edi write"]
  }
}
```

The `detail` object contains:

- `direction`: `"inbound"` or `"outbound"`, meaning **the step's** transfer direction, not the document's. A webhook delivering an inbound document to your endpoint records `"outbound"`, because the HTTP call leaves Tediware; so does one of the two steps behind an automatic 997. For the document's direction, read the transaction or the feed entry.
- `partner`: the trading partner this result belongs to, as `{ "key": "..." }`. The `key` is the partner's stable identifier in Tediware. Every result a partner's flow produces carries it, failed steps included, whichever way the document arrived. Route on it rather than on the ISA sender id, which several partners can share
- `errorMessage`: present when the processing step encountered an error. One sentence. For an implementation validation failure it carries the count and the first violation, for example `1 error: /heading/beginning_segment_for_invoice_BIG must have required property 'date_01'`, with `(and 2 more)` when there are others; the full list is in `errors`. Legacy: results written before September 2026 may carry the validator's or the mapping service's JSON reply inside the sentence. Do not parse it; read `errors`
- `incomingResultId`: on a failed result, the id of the result the failing step received. Read its payload (below) to see the document the step refused. Successful results do not carry it
- `errors`: an array of strings, present when the step recorded its findings individually. Implementation validation does, one entry per violation. A mapping that fails to run records one entry, led by the line and column in the mapping's transformation when the failure has a location, for example `line 12, column 5: Expected ")" before end of expression`. This is the field to read. On older results the same list is derived from `errorMessage` when the message carries it, so the two generations answer alike
- `webhook`: on a result written by a webhook delivery, the call it made: the `url`, the endpoint's `statusCode` and, on a failure, the response's `contentType`, the `attempts` made and `willRetry`. `attempts` counts every call made for this delivery, including retries run on the job queue. `maxAttempts` (6) is present whenever the failure was one Tediware retries (a 500, 502, 503 or 504, 429, a timeout, or a refused or reset connection); it is absent when the failure was final on its first answer, such as a 400, and there is no status when nothing answered. `willRetry` is always `false` on this result, because it is written only once retries are exhausted or the failure was never retryable, so there is nothing left to wait for: redeliver the document (inbound) or resend it (outbound) once the endpoint is fixed. The response body is not returned; your endpoint's own logs hold it
- `resend`: `true` when this result belongs to a replay of an earlier delivery, a resend or a redelivery, rather than the original. A replay lands on the original trace, so this is what distinguishes the two on a trace that holds both
- `mappingFailed`: `true` when an inbound mapping failed on this document, meaning the output is not guaranteed to be the canonical shape (see Inbound EDI). Absent when the mapping succeeded or no mapping is assigned.
- `mappingError`: describes what went wrong, present alongside `mappingFailed`. An object with a `kind`, a `message`, and for validation failures an `errors` array. `kind` is `"expression"` when the transformation failed to run (the output is the untransformed translation) or `"validation"` when the transformation ran but its output did not match the canonical shape (the output is the mapped document, delivered as produced)
- `warnings`: the warnings this step raised, present when there are any. Each is an object with a stable `code`, a `message` in prose, and an optional `detail` whose shape depends on the code. A warning is something worth reviewing that did not stop delivery, and it belongs to the step that raised it, so a trace lists each one once. The codes and their `detail` shapes are listed under Warning codes on the [EDI Transactions](/resources/api-docs/edi-transactions) page. The transaction gathers the warnings across its results as `warnings` and counts them as `warningCount` (see [EDI Transactions](/resources/api-docs/edi-transactions))
- `x12`: EDI-specific metadata including sender/receiver identifiers, transaction set code, and control numbers
- `usageIndicator`: the transaction's ISA15, `"P"` for production or `"T"` for test. Present on every result for an inbound document from the step that splits the interchange into transaction sets onward, including the result an inbound webhook points at, and on every result for an outbound document. A test document goes through the same flow and to the same webhook as a production one, so read this field when your system should handle the two differently. The transaction carries the same value (see [EDI Transactions](/resources/api-docs/edi-transactions)). Absent on results written before the field existed, and on an inbound document whose transaction could not be recorded
- `artifacts`: references to the files produced at this step. Each artifact has an `id`, a `usage`, and a `contentType` (the file's MIME type: `"application/json"` for JSON, `"application/edi-x12"` for EDI; older results created before content types were recorded may omit it). The `usage` names the artifact's role in the flow. `"input"` is the document the flow received and `"output"` is the document it delivered: for inbound processing the input is the partner's EDI and the output is the delivered JSON, and for outbound the input is your JSON and the output is the generated EDI. Other `usage` values name intermediate documents kept alongside them; on a mapped inbound result, `"translation"` is the parsed JSON the mapping received. Select artifacts by `usage`, since more than one can share a `contentType`.
- `filename`: on each artifact, the name the file was stored under. Present when the step that produced it recorded one. It is not always meaningful: when no name was supplied, Tediware generates one from a UUID, and artifacts written before filenames were recorded omit the field.
- `transformations`: the processing steps that ran on this result, in order. Use it to diagnose what did or did not execute, for example whether an inbound mapping ran on a document. Step names are internal labels, ranging from identifiers like `edi_to_json` to phrases like `implementation validation + edi write`; they are not the node names shown in the Tediware UI, and their naming and granularity change as flows evolve and as Tediware changes internally. Treat this as diagnostic detail rather than a stable contract. Do not branch on its contents.
- `sftp`: where the document came from or went, on results that moved over SFTP. Present in two shapes. A document Tediware fetched from a partner carries `filename`, `path`, `host`, `directory`, and `fetchedAt`; a document Tediware uploaded carries `filename`, `directory`, `host`, and `uploadedAt`, with no `path`. The `host` is your own SFTP connection. Absent on documents that arrived or left another way, such as AS2 or the API.

Artifact pointers accumulate down a flow, so a late step's `artifacts` array repeats what earlier steps produced. That is right for a single result and wrong as a picture of the run: use [`GET /platform/traces/:guid`](/resources/api-docs/traces), which lists each artifact once with the step that produced it.

## Read a Payload

```
GET /platform/results/:id/payload
```

Returns the result's payload: the data that step produced, kept on the result. An artifact is different: a stored file that a result's `detail.artifacts` points to, downloaded from `GET /platform/artifacts/:id`. Intermediate steps that store no artifact still keep a payload, such as a mapping's output before validation. A step that only moves a document on, such as an SFTP upload, may keep none, and its payload endpoint answers `404`.

```json
{
  "format": "json",
  "contents": {
    "transactions": [ { "B10": { "reference_identification_01": "PRO4471" } } ]
  }
}
```

`format` is the kind of data, for example `json` or `edi`, and `error` on a failed step. `contents` is the data itself: an object for JSON, a string for EDI. A failed step's payload holds only its error message; to see what it was given, read the payload of its `detail.incomingResultId`.

Query parameters:

- `jsonPath`: a dot-separated path into `contents`, for example `transactions.0.AT7`. Numeric segments index arrays. The response carries the value at that path as `contents`, and echoes `jsonPath`
- `keysOnly`: `true` replaces `contents` with its shape: keys, value types and array lengths (with the first element as a sample), four levels deep. Use it to find the path before reading the values

The response is the whole payload, however large. A payload for a big document can run to several megabytes, since every step keeps its own copy; use `jsonPath` or `keysOnly` when you only need part of it. The MCP `result_payload` tool refuses payloads over 256 KB and points here.

A sandbox key can read the payload of any result its sink received, as it can the result itself.

Results are kept for 45 days, apart from those linked to billing records or logs. A `404` names the id and says so, since a result id from an older run may simply have aged out. A `jsonPath` that does not resolve is also a `404`, and the message names the path.

```bash
curl "https://tediware.com/platform/results/4c2021f8-8310-4628-80f9-b578d4d68e11/payload?jsonPath=transactions.0.AT7" \
  -H "Authorization: Key your-api-key-here"
```

## Download an Artifact

```
GET /platform/artifacts/:id
```

Downloads the actual file content for an artifact. The response is the raw file with its original filename and content type, not a JSON response.

Artifact IDs are found in the `detail.artifacts` array of a result response.

```bash
# Download an artifact and save to a file
curl "https://tediware.com/platform/artifacts/b613c64c-dcba-4321-fe65-987654321098" \
  -H "Authorization: Key your-api-key-here" \
  -o output.edi
```

Returns `404` if the artifact does not exist or its file is not available.
