FlyDocs does two things: it makes AI coding tools follow your team’s process, and it keeps your PM tool in sync with what’s actually happening in the code. The relay API is the piece doing most of the second job.

This post walks through a single relay request end to end.

What the relay is

The relay is a thin, provider-agnostic API that sits between the FlyDocs CLI and your project management tool. When a developer runs /activate, /capture, or any other workflow command, the CLI doesn’t talk to Linear or Jira directly. It talks to the relay, and the relay talks to the provider on your behalf.

That extra hop sounds like complexity you wouldn’t want. Here’s why it earns its place:

  • One configuration source. Status mappings, label config, provider team selection, and skill set all live on the workspace, not in each developer’s local install. Update once, and every CLI session picks up the new config on its next request.
  • One credential. Each developer authenticates with a single fdk_ API key. Provider tokens live encrypted on the server and only get decrypted when the relay is actively making a call. Developers never see them or have to rotate them.
  • Provider abstraction. Linear’s GraphQL and Jira’s REST API have very different shapes. The relay normalizes both into one set of FlyDocs operations. Skills and scripts target the relay, not the provider, so adding a new provider doesn’t ripple through the workflow surface.
  • Auditability. Every workflow operation lands as a relay request with a trace ID. When something looks off in Linear, you have a clean log of what FlyDocs did and when.
DeveloperCLIFlyDocs Relaytranslates & routesProviderLinear / Jira

What happens on a single request

Here’s what happens when a developer’s IDE runs issues.py transition FLY-123 IMPLEMENTING "Starting work":

  1. The script POSTs to the relay with the developer’s API key, which the relay verifies against a SHA-256 hash. The plaintext key never lives on our servers after creation.
  2. The relay resolves the workspace configuration from Convex: provider type, team binding, status map, label map.
  3. The relay loads the encrypted provider credential and decrypts it with AES-256-GCM in memory for the lifetime of this single request. Nothing about the credential touches a log or a response.
  4. The relay translates IMPLEMENTING to the provider’s native status (e.g. Linear’s In Progress state ID for your team) using the workspace’s status map.
  5. The relay calls the provider’s API and returns a normalized result.
  6. After the response, the in-memory plaintext credential is dropped. A usage log row gets written with the endpoint, status code, latency, and provider. Request and response bodies are not logged.
1Authenticate2Resolve config3Decrypt4Translate5Call provider6Drop & log

That’s the entire flow. There is no caching layer, no background job, no batched sync. The relay is a translator, not a copy of your data.

What the relay stores

What lives on our servers, persistently:

  • Workspace configuration (status maps, label maps, provider team binding, skill set).
  • Identity records (user, organization, membership).
  • Provider credentials, AES-256-GCM encrypted at rest, never returned in API responses.
  • API key SHA-256 hashes plus a short plaintext prefix (fdk_a1b2…) we display in the dashboard so you can identify keys at a glance.
  • Generated context (project.md, service descriptors, stack detection), only when you opt into a codebase scan, and never including raw source code.
  • Usage logs (request metadata, no bodies) for 90 days.

What does not live on our servers, ever:

  • Source code, file contents, git history.
  • Plaintext provider credentials.
  • Plaintext FlyDocs API keys.
  • Request or response bodies from relay calls.
StoredWorkspace configIdentity recordsEncrypted credentialsAPI key hashesGenerated contextUsage logs (90 days)Never storedSource codeGit historyPlaintext credentialsPlaintext API keysRequest / response bodiesSecrets in your code

The privacy policy spells this out at the file-path level, naming the parts of our codebase that back each claim. If you read source instead of marketing copy, that page and the security reference are the docs for you.

What happens when the relay is down

This is the part that sells the architecture. If the relay is unreachable, your workflow does not break.

FlyDocs’s enforcement layer (hooks, skills, status transitions, formatting, stop-gates) runs on the developer’s machine, against locally installed files. When the CLI hits a relay-dependent operation like creating an issue or transitioning a ticket, it fails clearly and queues the operation locally if appropriate. When the relay comes back online, the developer re-runs and it lands. The AI session keeps going. Only external PM sync pauses.

Compare that to integrations that route the AI’s tool calls directly through a vendor API: those go down with the vendor. Ours doesn’t.

Why workspace configuration lives on the server

Status mappings and label config don’t live in a repo file. They live on the workspace, and that’s deliberate.

These are team-level decisions, not repo-level ones. When an engineering manager decides that IMPLEMENTING maps to Linear’s In Progress state, that change needs to reach every developer’s CLI on the next session, without anyone pulling a config commit. Server-side workspace config is the difference between “we follow the same process” and “we used to follow the same process before someone forgot to merge their branch.”