# Response formats

One search resource, six spellings of the answer. Pick with `format=`; JSON is the default and the one the others are described in terms of.

| `format` | Content-Type | Shape |
| --- | --- | --- |
| `json` | `application/json` | One object, results in an array. |
| `ndjson` | `application/x-ndjson` | One JSON object per line. The first line is the metadata, tagged `"object":"meta"`. |
| `xml` | `application/xml` | The same document as XML, rows as `<result>`. |
| `csv` | `text/csv` | Semicolon separated, no header line. |
| `tsv` | `text/tab-separated-values` | As CSV, tab separated. |
| `txt` | `text/plain` | One url per line. |

`jsonl` is accepted as another name for `ndjson`.

## Which to use

**json** for anything that fits in memory. **ndjson** for anything that does not: there is no enclosing array to wait for, the metadata arrives before the rows, and a reader can start work on the first result while the rest is still arriving. **csv**, **tsv** and **txt** for spreadsheets, shell pipelines, and for moving a script over from the old export urls without changing its parser.

## ndjson

```
{"object":"meta","query":"\"angular.min.js\"","page":1,"per_page":2,"total":278,"total_pages":139,"returned":2,"truncated":false,"took_ms":2}
{"domain":"imgbox.com","url":"https://imgbox.com/","rank":4187,"ranked":true}
{"domain":"angularjs.org","url":"https://angularjs.org/","rank":12376,"ranked":true}
```

## Choosing the columns

`json` and `xml` return every field. The flat formats default to the familiar ones instead, so a script coming from the old export urls needs no parser change:

| Request | Output |
| --- | --- |
| `format=csv` | `imgbox.com;4187` |
| `format=csv&columns=url,rank` | `https://imgbox.com/;4187` |
| `format=csv&columns=domain` | `imgbox.com` |
| `format=txt` | `https://imgbox.com/` |
| `format=csv&snippets=1` | `imgbox.com;4187;the matching text` |
| `format=csv&header=1` | a `domain;rank` line first |
| `format=csv&delimiter=,` | `imgbox.com,4187` |

`columns` works for every format, so `format=json` with `columns=domain` returns objects with only that field.

## Details of the flat formats

- A value is quoted only when it would otherwise break the row - it contains the delimiter, a quote or a newline. Ordinary `domain;rank` output is bare.
- Quotes inside a quoted value are doubled, as CSV expects.
- Snippets, being a list, are joined with `...` into one cell.
- An unranked site has an empty rank cell, which is how `null` spells itself here.
- The totals cannot fit in a row, so they are in the `X-Total-Results`, `X-Returned-Results` and `X-Truncated` headers instead. Those are sent for every format.

These are the new API's own serialisations, not a reissue of the old exports. The shape is familiar on purpose, but only [the old urls](https://publicwww.com/docs/api/legacy/) promise the exact bytes.

## Formats and errors

`csv`, `tsv` and `txt` are shapes for rows and nothing else, so asking for one on `/v1/account` is `400 format_not_available`. Errors themselves come back as JSON, or as XML if that is what was asked for.

Source: https://publicwww.com/docs/api/formats/
