Integrations
Connections in, keys in, hooks out
A finance system exports a file every month, somebody has to drag it in, and they forget. So a twin can connect to the systems you already keep and read them every day. Anything else can post to the feed with a key. Going the other way, a hook is a URL the twin calls when something happens, signed so you can check it came from here.
Connections
Five systems a twin reads every day
Open Connections on a twin, pick one, and give it a read only key, a sign in or a link. It pulls the last twelve months at once and then once a day, fills the monthly actuals the monitor compares against, and replaces its own files so the twin is rebuilt on fresh figures. Operator and above.
| System | How it connects | What it reads |
|---|---|---|
| QuickBooks Online | Sign in with QuickBooks | The profit and loss month by month, the bank balances, and sales by customer |
| Xero | Sign in with Xero | The profit and loss month by month, the bank balances, and invoiced sales by customer |
| Stripe | A restricted key with read access | Subscriptions and paid invoices: revenue by month, customers, churn, and what each customer pays |
| HubSpot | A private app token with read access | Companies and deals: your customers, what each has bought, the open pipeline, the win rate and the sales cycle |
| A spreadsheet link | A link anybody with it can open, such as a shared Google Sheet | Monthly actuals by column, or any kind of file, read again every day |
Every connection only reads. Its key or token is sealed before it is stored and is never shown again. The owner hears about a failed pull, and five in a row pause it. Removing it signs out of QuickBooks or Xero and deletes the token.
Keys in
Post a file, or a month of actuals, from a machine
A key is minted on the twin, shown once, and stored as a hash. It goes in a header. With it, a POST to the feed with a file and its kind does exactly what a person dragging that file in does: the file is registered, the reader for its kind runs, and the facts land. A POST to the actuals feed with a month of figures does what the monitor's paste box does.
Every use is counted and dated on the key's row, so a key that stops being used is visible, and a key can be revoked in one click, at which point anything still holding it gets a refusal on the next call.
The calls are plain enough to put in a scheduled job in whatever runs your exports. The application shows the exact curl for both, with the twin's own feed URL filled in.
- One key per system, named after it
- Hashed at rest, shown once
- Counted, dated, revocable
Hooks out
Thirteen events a hook can subscribe to
| Event | When it fires | What the body carries |
|---|---|---|
| analysis.completed | An analysis finishes | The question, the answer, the confidence and the coverage |
| run.completed | A scenario run finishes | The scenario, the deltas at the horizon and the cash risk |
| decision.approved | A reviewer or the owner approves | The decision, its band and its signatures |
| decision.outcome | An outcome is recorded | The decision with its outcome and whether it landed inside |
| stress.completed | The battery finishes | The resilience score, the weakest point, how many break |
| drift.flagged | The monitor calls drift | The metrics drifting and the plain sentence |
| source.added | A file lands through the feed | The source and how many facts it produced |
| alert.raised | A rule raises an alert | The rule, the severity, the title and the plain sentence |
| proposal.made | Somebody proposes a change to the ledger | The row, the value proposed and the reason |
| proposal.decided | A proposal is approved or rejected | The row, the value and the verdict |
| scenario.changed | A watched scenario changes its answer | The scenario, the new and the last run, and the plain sentence |
| connector.synced | A connection brings in new figures | The connection and what it brought in |
| connector.failed | A connection cannot reach its system | The connection and the reason |
Every delivery carries an event header, a timestamp header and a signature header: HMAC SHA-256 over the timestamp, a dot and the raw body, with the hook's own secret. The secret is shown once when the hook is added. A hook that fails ten times in a row pauses itself and says so.
Kept
What the integrations screen shows
- Per key
- 3uses, last used, made
- Per hook
- 4state, failures in a row, last delivery, and a test button
- Per delivery
- 4the event, the answer code, how long it took, and the body
- Secrets shown
- 1 timethen hashed or kept server side, never listed again
Boundaries