> For the complete documentation index, see [llms.txt](https://docs.wingbits.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.wingbits.com/wingbits/guides-2/nats-integration/nats-technical-integration.md).

# Technical integration guide

This guide describes the production contract for consuming the Wingbits live flight feed over NATS. It is intended for engineering teams building a long-running consumer or forwarding the feed into Kafka.

Last reviewed: 6 August 2026.

For credential setup and a command-line walkthrough, start with the [NATS onboarding guide](/wingbits/guides-2/nats-integration/nats-flight-stream.md).

## Current service contract

| Item                | Current behavior                                                 |
| ------------------- | ---------------------------------------------------------------- |
| Endpoint            | `nats://nats-cluster.wingbits.com:4222`                          |
| Authentication      | NATS JWT and NKey credentials in a `.creds` file                 |
| Authorization       | Subscribe-only access to the subjects granted to your account    |
| Payload             | One UTF-8 JSON object per NATS message                           |
| Payload compression | None on the currently published NATS subjects                    |
| Delivery model      | Core NATS, best effort and at most once                          |
| Replay              | Not available                                                    |
| Server availability | Three-node, multi-AZ NATS cluster behind a network load balancer |

{% hint style="danger" %}
The credentials file is a secret. Do not commit it, include it in logs, paste it into support messages, or bake it into a container image. Mount it at runtime from your secret manager.
{% endhint %}

The production endpoint currently uses the `nats://` URI above. The credentials authenticate and authorize the client; they do not by themselves encrypt the network transport. If TLS is required by your production security policy, confirm that requirement with Wingbits before go-live.

## Subjects and authorization

Your Wingbits contact will provide the exact subject authorized for your account. Copy that subject exactly when subscribing. A scoped trial may use a different subject from the standard streams below.

NATS supports two subject wildcards:

* `*` matches exactly one token.
* `>` matches one or more trailing tokens and must be the final token.

These wildcards are not interchangeable when permissions are scoped. For example, credentials authorized for a subject ending in `.*` can be denied when they try to subscribe with `.>`. A wildcard subscription never bypasses the grants in your credentials.

Use the subject supplied by Wingbits for the first test:

```shell
nats sub "<SUBJECT_FROM_WINGBITS>"
```

Accounts with standard feed access can use these subjects:

| Standard subscription | Update rate                                                                    | Typical use                  |
| --------------------- | ------------------------------------------------------------------------------ | ---------------------------- |
| `flights.full.>`      | Every deduplicated update, currently up to about twice per second per aircraft | Lowest-latency tracking      |
| `flights.5s.>`        | At most one update per aircraft every 5 seconds                                | General live applications    |
| `flights.dd.>`        | At most one update per aircraft every 10 seconds                               | Lower-bandwidth applications |

Individual messages use subjects such as `flights.full.<icao>`, where `<icao>` is the six-character ICAO hex identifier. NATS subjects are case-sensitive, so preserve the value exactly as received. Standard subject examples:

```
flights.full.>         all full-rate aircraft granted to the account
flights.full.7820d9    one aircraft
```

Optional subjects such as `flights.acas` and `flights.adsc` are available only when explicitly enabled for the account.

Avoid overlapping subscriptions on the same connection. For example, subscribing to both `flights.full.>` and `flights.full.7820d9` delivers the matching aircraft message twice to that connection.

## Payload and timestamps

Each current flight subject carries one uncompressed JSON object. The NATS message boundary is the record boundary, so no newline or length prefix needs to be parsed.

The common field reference is in the [onboarding guide](/wingbits/guides-2/nats-integration/nats-flight-stream.md#understanding-the-data). Fields may be absent when the aircraft did not report them. Consumers must treat all non-identity fields as optional and tolerate new fields being added.

Important fields for integration logic include:

| Field       | Meaning                               | Consumer guidance                                                 |
| ----------- | ------------------------------------- | ----------------------------------------------------------------- |
| `h`         | ICAO hex identifier                   | Must match the final token in a per-aircraft NATS subject exactly |
| `ra`        | Source received-at time, when present | Preferred event-time value for per-aircraft ordering              |
| `timestamp` | Pipeline timestamp, when present      | Useful as a fallback, not as a unique message ID                  |

Do not use local receipt time as the only ordering key. Network and reconnect behavior can change arrival timing. For stateful processing, partition by `h`, order by the event time carried in the payload, and make writes idempotent.

There is no globally unique message ID in the current payload. A practical dedupe key can combine the subject, event time, and a payload hash. If neither event-time field is present, use the subject and a canonicalized payload hash within a bounded dedupe window; identical repeated states may otherwise be indistinguishable.

## Delivery and ordering semantics

The live subjects use Core NATS rather than a persisted JetStream consumer. This has several consequences:

* Delivery is at most once.
* Only connected subscribers receive a live message.
* Messages published while your consumer is disconnected are not replayed.
* NATS preserves publication order from one publisher to one subscriber.
* There is no total ordering guarantee across multiple publishers or a reconnect boundary.
* A slow consumer can lose messages or be disconnected. Reading continuously is part of the client contract.

If your application requires durable replay or an at-least-once contract, raise that requirement with Wingbits. The current subjects do not provide it. See the NATS documentation on [Core NATS and JetStream delivery](https://docs.nats.io/nats-concepts/jetstream/consumers) and [slow consumers](https://docs.nats.io/running-a-nats-service/nats_admin/slow_consumers).

## Queue groups

Use a queue group when one consumer cannot process the feed fast enough. Give each worker the same subject and queue name. NATS then delivers each message to one available member of the group, allowing the workers to share the load.

Starting this command in multiple processes creates a shared worker group named `flight-workers`:

```shell
nats sub "<SUBJECT_FROM_WINGBITS>" --queue "flight-workers"
```

Keep these behaviors in mind:

* Members of one queue group share the feed. Each message is delivered to one member, not every member.
* Independent pipelines that each need the complete feed must use different queue names. Each queue group receives its own copy, while members within that group share the work.
* Members process messages concurrently, so completion order can differ from publication order. If per-aircraft order matters, partition downstream work by ICAO hex and use event time, or tolerate out-of-order state updates.

See the NATS documentation on [queue subscriptions](https://docs.nats.io/using-nats/developer/receiving/queues).

## Availability and reconnect behavior

The Wingbits endpoint is backed by a three-node NATS cluster distributed across multiple AWS availability zones and fronted by a network load balancer. The cluster and load balancer reduce the impact of a single server or zone failure.

Production consumers must still configure and observe reconnect behavior:

1. Use an official NATS client library and enable automatic reconnects.
2. Retry indefinitely, or for a duration consistent with your availability requirements.
3. Add reconnect delay and jitter to avoid a reconnect storm.
4. Record disconnect, reconnect, asynchronous error, and permanently closed events.
5. Confirm subscriptions are active after reconnect. Official clients normally restore them automatically.
6. Track the time between the last message before disconnect and the first message after reconnect. That gap cannot be backfilled from Core NATS.

High availability protects endpoint access. It does not change the at-most-once delivery contract.

## Consumer design and backpressure

The subscription callback should do as little work as possible:

1. Copy or hand off the NATS payload to a bounded local queue.
2. Return from the callback promptly.
3. Parse, validate, and write downstream in worker processes.
4. Monitor local queue depth, processing latency, disconnects, and dropped data.

Do not perform slow database calls or synchronous Kafka delivery directly in the NATS callback. If the callback does not keep reading quickly enough, the server-side pending buffer can fill and the connection can be treated as a slow consumer. Because the feed is not persisted, those live messages are not replayed.

If one consumer cannot keep up after moving downstream work out of the callback, run multiple consumers in the same queue group.

## Kafka integration

Wingbits provides the NATS endpoint. A Kafka bridge runs in your environment and publishes the received values into your Kafka cluster. The official [NATS-Kafka Bridge](https://github.com/nats-io/nats-kafka) supports a Core NATS-to-Kafka connector.

The following is a starting template. Replace the subject, credential path, brokers, and topic with your own values:

```
reconnectinterval: 5000,
connecttimeout: 5000,

nats: {
  servers: ["nats://nats-cluster.wingbits.com:4222"],
  usercredentials: "/run/secrets/wingbits-nats.creds",
  reconnectwait: 1000,
  maxreconnects: -1,
}

connect: [
  {
    type: "NATSToKafka",
    id: "wingbits-flights-to-kafka",
    subject: "<SUBJECT_FROM_WINGBITS>",
    # Set the same queuename on every replica to share subscription load.
    # queuename: "wingbits-bridge-workers",
    brokers: ["broker-1.example.com:9092", "broker-2.example.com:9092"],
    topic: "wingbits-flights",
    balancer: "hash",
    keytype: "subject",
  },
]
```

Using the NATS subject as the Kafka key keeps updates for one aircraft on the same Kafka partition when the ICAO hex is the final subject token.

Operational notes:

* If one bridge cannot keep up, run multiple bridge instances with the same `queuename` so they share the NATS subscription load.
* Multiple bridge instances in one queue group can publish related updates to Kafka concurrently, so consumers must tolerate out-of-order events.
* Use a different `queuename` for every independent Kafka pipeline that needs a complete copy of the feed.
* A bridge outage creates a gap because the source is Core NATS and has no replay.
* The bridge passes the current JSON payload through as the Kafka message value.
* Kafka retention begins only after the bridge has successfully written the message to Kafka.
* Configure Kafka TLS, SASL, monitoring, and alerting according to your own platform requirements.

If uninterrupted capture through bridge maintenance is required, agree the durability and failover design with Wingbits before production deployment.

## Compression

The current NATS flight subjects are not payload-compressed. They contain the JSON bytes directly.

This differs from compressed TCP delivery, which may use a length prefix and a gzip-compressed payload. NATS already provides a message boundary and payload length, so TCP framing is not present on the current NATS subjects.

NATS cluster route compression is an internal server-to-server optimization. It does not compress the payload delivered to a customer subscriber. Do not try to gzip-decode messages received from the current flight subjects.

## Production readiness checklist

Before go-live, verify all of the following:

* [ ] The credentials file is loaded from a secret manager and is not in the image.
* [ ] The exact intended subject is authorized and produces data.
* [ ] The consumer can sustain the peak message rate without a growing local queue.
* [ ] Disconnect and reconnect events are monitored and alerted.
* [ ] The application records and reports feed gaps.
* [ ] Processing is partitioned by ICAO hex when per-aircraft ordering matters.
* [ ] Writes are idempotent and tolerate optional or newly added fields.
* [ ] Kafka partition keys and retention have been verified, if Kafka is used.
* [ ] The current uncompressed payload bandwidth fits the production design.
* [ ] Any requirement for TLS, durable replay, or compressed NATS delivery has been agreed with Wingbits before go-live.

## Troubleshooting and support

When reporting an issue, include:

* UTC start and end time
* Exact NATS subject
* Client library and version
* Exact error text
* Disconnect and reconnect events
* Approximate message rate and local queue depth
* A redacted sample payload, if relevant

Never include the contents of the `.creds` file.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.wingbits.com/wingbits/guides-2/nats-integration/nats-technical-integration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
