# Direct Nominal channel writer

Writes data points directly to Nominal’s managed database offering.

OpenAPI file: [`DirectNominalChannelWriterService.json`](https://dev.nominal.io/api/_downloads/4730358a4d3c71adc774dabe8456f0b6/DirectNominalChannelWriterService.json)

## Endpoints

### Write batches

POST `/storage/direct-writer/v1`

Synchronously writes batches of records to a Nominal data source. This endpoint bypasses the Channel Writer service entirely, and should only be used if the implications are well understood.

If you call this endpoint, writes will go directly into Nominal DB and will not be placed in Nominal’s durable queue. This results in lower latency, but also consequently lower durability.

Body

`batches` array of [`RecordsBatch`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#recordsbatch)
:   ​

    Fields of `RecordsBatch`

    `channel` string required
    :   ​

    `tags` map of `TagName` to string
    :   ​

    `points` [`Points`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#points) required
    :   ​

        **string**

        Set `type` to `"string"`.

        `string` array of [`StringPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#stringpoint)
        :   ​

            Fields of `StringPoint`

            `timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
            :   ​

                Fields of `Timestamp`

                `seconds` integer (int64) required
                :   ​

                `nanos` integer (int64) required
                :   ​

            `value` string required
            :   ​

        **double**

        Set `type` to `"double"`.

        `double` array of [`DoublePoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#doublepoint)
        :   ​

            Fields of `DoublePoint`

            `timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
            :   ​

            `value` number required
            :   ​

        **log**

        Set `type` to `"log"`.

        `log` array of [`LogPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#logpoint)
        :   ​

            Fields of `LogPoint`

            `timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
            :   ​

            `value` [`LogValue`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#logvalue) required
            :   ​

                Fields of `LogValue`

                `message` string required
                :   ​

                `args` map of string to string
                :   ​

        **int**

        Set `type` to `"int"`.

        `int` array of [`IntPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#intpoint)
        :   ​

            Fields of `IntPoint`

            `timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
            :   ​

            `value` integer required
            :   ​

        **uint64**

        Set `type` to `"uint64"`.

        `uint64` array of [`Uint64Point`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#uint64point)
        :   ​

            Fields of `Uint64Point`

            `timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
            :   ​

            `value` integer (int64) required
            :   ​

        **array**

        Set `type` to `"array"`.

        `array` [`ArrayPoints`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#arraypoints)
        :   ​

            **double**

            Set `type` to `"double"`.

            `double` array of [`DoubleArrayPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#doublearraypoint)
            :   ​

                Fields of `DoubleArrayPoint`

                `timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
                :   ​

                `value` array of number
                :   ​

            **string**

            Set `type` to `"string"`.

            `string` array of [`StringArrayPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#stringarraypoint)
            :   ​

                Fields of `StringArrayPoint`

                `timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
                :   ​

                `value` array of string
                :   ​

        **struct**

        Set `type` to `"struct"`.

        `struct` array of [`StructPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#structpoint)
        :   ​

            Fields of `StructPoint`

            `timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
            :   ​

            `jsonString` string required
            :   ​

`dataSourceRid` string (RID) required
:   ​

`asynchronousInsert` boolean deprecated
:   Is always true - setting this to false will do nothing. **Deprecated:** Should not be used.

Response

No content (HTTP 204).

Request

**curl**

```shell
curl -X POST "https://api.gov.nominal.io/api/storage/direct-writer/v1" \
  -H "Authorization: Bearer <api key>" \
  -H "Content-Type: application/json" \
  --data '{
  "dataSourceRid": "<nominal data source or dataset rid>"
}'
```

**requests**

```python
import requests

response = requests.post(
    "https://api.gov.nominal.io/api/storage/direct-writer/v1",
    headers={"Authorization": "Bearer <api key>"},
    json={"dataSourceRid": "<nominal data source or dataset rid>"},
)
response.raise_for_status()
```

**httpx**

```python
import httpx

response = httpx.post(
    "https://api.gov.nominal.io/api/storage/direct-writer/v1",
    headers={"Authorization": "Bearer <api key>"},
    json={"dataSourceRid": "<nominal data source or dataset rid>"},
)
response.raise_for_status()
```

**aiohttp**

```python
import asyncio

import aiohttp

async def main() -> None:
    async with aiohttp.ClientSession() as session:
        async with session.post(
            "https://api.gov.nominal.io/api/storage/direct-writer/v1",
            headers={"Authorization": "Bearer <api key>"},
            json={"dataSourceRid": "<nominal data source or dataset rid>"},
        ) as response:
            response.raise_for_status()

asyncio.run(main())
```

Response: `204`

No content.

## Errors

[Errors](https://dev.nominal.io/api/legacy.md#errors) shows how these errors are sent.

Each error’s `errorName` is `NominalChannelWriter:` followed by its name below.

| Status | Name | Notes |
| --- | --- | --- |
| 400 | `ArrayTooLarge` | Array size exceeds maximum allowed length. |
| 400 | `ConflictingDataTypes` | Found two different data types for the same series in the request. |
| 400 | `ConflictingUnits` | Found two different units for the same channel in the request. |
| 400 | `DuplicateResolvedChannelName` | Multiple ingested columns resolve to the same channel name after applying channelPrefix and channelNameOverrides. Resolved channel names must be unique within a single ingest. |
| 400 | `InvalidChannelName` | The channel name is invalid. |
| 400 | `InvalidDataSource` | The nominal data source or dataset provided is invalid. |
| 400 | `InvalidStruct` | Ingested Struct is not a valid JSON struct |
| 400 | `InvalidTelegrafTimestamp` |  |
| 400 | `InvalidTimestamp` |  |
| 400 | `MismatchedTimestampsAndValues` | Columnar streaming request contains different numbers of timestamps and values |
| 400 | `ReservedTagName` | The request uses a tag name that is reserved for internal use. Remove the tag from the request. |
| 400 | `StreamingDisabledOnDataset` | Unsupported dataset for streaming. |
| 400 | `StreamingSessionRidNotAllowed` | The request sets a streaming session rid, which is assigned by Nominal and cannot be provided by the client. |
| 400 | `StructTooLarge` | Struct value exceeds maximum allowed UTF-8 byte size. |
| 400 | `TooManyChannelNameOverrides` | The request specifies more channel name overrides than the maximum allowed. |
| 400 | `TooManySessionSources` | The dataset has exceeded the maximum number of distinct active session sources allowed per hour. This is a best-effort limit enforced per channel-writer instance. |
| 413 | `PointsTooLarge` | The size of the points being written exceeds the maximum allowed size. |

## Types

### ArrayPoints

Array points for the internal API for directly writing points which supports all points types.

Set `type` to the name of one of the other fields, and set only that field.

`double` array of [`DoubleArrayPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#doublearraypoint)
:   ​

`string` array of [`StringArrayPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#stringarraypoint)
:   ​

### DoubleArrayPoint

`timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
:   ​

`value` array of number
:   ​

### DoublePoint

`timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
:   ​

`value` number required
:   ​

### IntPoint

`timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
:   ​

`value` integer required
:   ​

### LogPoint

`timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
:   ​

`value` [`LogValue`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#logvalue) required
:   ​

### LogValue

`message` string required
:   ​

`args` map of string to string
:   ​

### Points

Points for internal API for directly writing points which supports all points types. Logs specifically are supported externally via a separate endpoint.

Set `type` to the name of one of the other fields, and set only that field.

`string` array of [`StringPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#stringpoint)
:   ​

`double` array of [`DoublePoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#doublepoint)
:   ​

`log` array of [`LogPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#logpoint)
:   ​

`int` array of [`IntPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#intpoint)
:   ​

`uint64` array of [`Uint64Point`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#uint64point)
:   ​

`array` [`ArrayPoints`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#arraypoints)
:   ​

`struct` array of [`StructPoint`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#structpoint)
:   ​

### RecordsBatch

`channel` string required
:   ​

`tags` map of `TagName` to string
:   ​

`points` [`Points`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#points) required
:   ​

### StringArrayPoint

`timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
:   ​

`value` array of string
:   ​

### StringPoint

`timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
:   ​

`value` string required
:   ​

### StructPoint

`timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
:   ​

`jsonString` string required
:   ​

### Timestamp

Deprecated for new APIs. Use google.protobuf.Timestamp for absolute instants in proto APIs.

This legacy nanosecond precision timestamp type is represented by an epoch time in seconds and a nanosecond offset. The nanosecond offset is from the start of the epoch second, so must be less than 1 billion.

`seconds` integer (int64) required
:   ​

`nanos` integer (int64) required
:   ​

### Uint64Point

`timestamp` [`Timestamp`](https://dev.nominal.io/api/rest/direct-nominal-channel-writer.md#timestamp) required
:   ​

`value` integer (int64) required
:   ​

Page design based on [Scalar](https://scalar.com), MIT License.
