SDKOverview & reference

SDK reference

@eda-holding-inc/sdk is a zero-dependency TypeScript client. It runs on Node ≥ 18, edge runtimes (Vercel/Cloudflare), Deno, Bun, and browsers — anywhere with fetch. Everything is fully typed.

bash npm install @eda-holding-inc/sdk

Constructing a client

import { Eda } from "@eda-holding-inc/sdk";
 
const eda = new Eda({
  apiKey: process.env.EDA_API_KEY!, // required (or set EDA_API_KEY and omit)
});

Options

OptionTypeDefaultNotes
apiKeystringprocess.env.EDA_API_KEYYour eda_live_… / eda_test_… key.
baseUrlstringhttps://api.edahq.comPoint at a self-hosted/proxy endpoint.
agentstringDefault agent name; per-call agent overrides it.
failMode"closed" | "open""closed"On transport failure: block (safe) or allow.
retryRetryOptions | falsesensible retriesRetries idempotent calls with backoff.
cacheCacheOptions | falseoffShort-TTL cache of identical checks.
localRulesLocalRule[]Offline pre-checks before hitting the API.
redactParamsstring[]sensible defaultsParam keys stripped before leaving the process.
dryRunbooleanfalseEvaluate + log intent without enforcing (returns approved).
fetchtypeof fetchglobal fetchInject a custom fetch (edge, mocks, proxies).
timeoutMsnumber10000Per-request timeout.

Read the key from the environment and you can construct with no arguments: const eda = new Eda();

check(request)

The core call. Ask whether an action is allowed.

const decision = await eda.check({
  agent: "support-agent",       // optional if you set a default agent
  action: "refund_customer",    // required
  params: { amount: 120, customerId: "cus_8842" },
  metadata: { requestId: req.id },
});
 
// decision.status: "approved" | "blocked" | "pending" | "denied"
// decision.reason, decision.actionId, decision.policy?, decision.risk?

Use the predicates if you prefer:

import { isApproved, isBlocked, isPending, isDenied } from "@eda-holding-inc/sdk";
if (!isApproved(decision)) return handleBlocked(decision);

checkAndWait(request, options?)

Check, and if the result is pending, block until a human decides (or the timeout elapses, which throws EdaPendingTimeoutError).

const decision = await eda.checkAndWait(
  { agent: "support-agent", action: "wire_transfer", params: { amount: 50_000 } },
  { timeoutMs: 10 * 60_000, pollMs: 2_000 },
);

getDecision(actionId)

Fetch the current decision for a previously created action — the deferred-approval path (e.g. resume from a webhook or job).

const decision = await eda.getDecision(actionId);

waitForApproval(actionId, options?)

Poll a pending action until it’s approved/denied or times out.

const decision = await eda.waitForApproval(actionId, { timeoutMs: 300_000 });

guard(agent, action, fn) and protect(...)

Wrap any async function so it’s gated automatically — the returned function checks first and only runs fn when approved.

const refund = eda.guard("support-agent", "refund_customer", async (input) => {
  return stripe.refunds.create(input);
});
 
await refund({ charge: "ch_…", amount: 120_00 }); // throws EdaDeniedError if not approved

protect is the same idea with an options object for custom param extraction and wait behavior. See adapters for framework-specific wrappers built on top of these.

checkMany(requests)

Evaluate a batch in one round-trip. Returns decisions in order.

const decisions = await eda.checkMany([
  { agent: "ops", action: "scale_up", params: { replicas: 10 } },
  { agent: "ops", action: "delete_bucket", params: { name: "prod-logs" } },
]);

Introspection

MethodReturns
eda.listActions(opts?)Recent actions (paginated with a cursor) for the audit trail.
eda.usage()Current plan, quota used/included, and AI token usage this period.
eda.health()API status + version.
eda.stats()Client-side counters (checks, blocks, cache hits) for observability.
const { items, cursor } = await eda.listActions({ status: "blocked", limit: 50 });
const usage = await eda.usage();

TypeScript types

All request/response shapes are exported: ActionRequest, Decision, DecisionStatus, CheckResult, ActionRecord, ApprovalState, UsageSnapshot, LocalRule, Condition, ConditionOp, and the client option types (EdaOptions, RetryOptions, CacheOptions, GuardOptions, WaitOptions).

import type { ActionRequest, Decision, DecisionStatus } from "@eda-holding-inc/sdk";

Next