XpectraFlow docs
Commands

How command delivery works

XpectraFlow never talks to your vehicle. It hands the command to your system, and you own the last mile.

Start with what we do not do

XpectraFlow does not transmit to your vehicle. Not over MAVLink, not over a radio, not at all. The ingest path binds sockets it never writes to; there is no command message on any telemetry subject, and a test asserts it stays that way.

That is a deliberate boundary, not an unfinished feature. The moment a system can command a vehicle it inherits a regulatory surface, and we would rather not stand between your operator and your aircraft.

So when an operator issues a command in the Command Center, this is what happens: we POST a signed notification to an HTTPS endpoint you registered, and your system decides what to do with it. You own the last mile. You keep the interlocks, the radio, and the responsibility.

If you do not register a webhook endpoint, the Command Center is a log. Commands are recorded, annotated on the chart, and never sent anywhere. That is a perfectly reasonable way to use it, and it is the default.

The sequence

sequenceDiagram
    participant Op as Operator (console)
    participant XF as XpectraFlow
    participant Q as Command queue
    participant You as Your receiver
    participant V as Your vehicle

    Op->>XF: log a command
    Note over XF: status: logged<br/>nothing is sent
    Op->>XF: POST /api/commands/dispatch
    XF->>XF: kill switch? armed? endpoint?
    XF->>Q: queue it
    Note over XF: status: queued
    Q->>You: POST, HMAC-signed
    You-->>Q: 200
    Note over XF: status: delivered
    You->>V: your uplink, your rules
    V-->>You: accepted
    You->>XF: POST /api/commands/ack
    Note over XF: status: acked

Note where the vehicle appears: only on your side of the diagram.

The states

StateMeans
loggedRecorded. Nothing has been sent.
queuedDispatched, waiting to go out
deliveredYour endpoint returned 2xx
ackedYour system reported the vehicle took it
nackedYour system reported it was rejected
timed_outDelivered, and then silence past the deadline
failedFive delivery attempts, or your endpoint refused it
retractedAn operator withdrew it

delivered does not mean the vehicle heard anything. It means your server returned a 2xx. The word is not transmitted, deliberately — in eighteen months somebody reading this database should not be able to conclude that we transmit.

acked is the state that means something reached a vehicle, and it is a state only you can put a command into.

timed_out is the one worth watching. It means we handed the command over and heard nothing back, so nobody knows whether the vehicle acted. That ambiguity is exactly what an operator needs to see rather than have smoothed over.

What you have to build

Register an endpoint

POST /api/webhooks/create gives you a signing secret, once. See the webhooks reference.

Build a receiver

Verify the signature, respond 2xx quickly, and do the uplink asynchronously. The receiver guide has working code in Python and Node.

Arm the dataset

Nothing is delivered for a dataset that is not armed, and arming expires. See Arming.

Acknowledge

Tell us what the vehicle did, using the one-time token in the payload. Without this every command ends at timed_out.

The three things that will surprise you

Next

On this page