> ## Documentation Index
> Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Base Class

> The StatefulActor base class — subclass it, declare async methods, and they become RPC-callable from a stub. Holds this.ctx and this.env.

`StatefulActor` is the base class you extend. Subclass it, declare async methods, and they become RPC-callable from a stub. It holds `this.ctx` (see [Actor Context](/docs/edge-compute/stateful-actors/api-reference/context)) and `this.env` (your bindings).

```ts theme={null}
import { StatefulActor } from "@telnyx/edge-runtime";

export class Account extends StatefulActor {
  async debit(amount: number): Promise<{ ok: boolean; balance: number }> {
    const balance = (await this.ctx.storage.get<number>("balance")) ?? 0;
    if (balance < amount) return { ok: false, balance };
    await this.ctx.storage.put("balance", balance - amount);
    return { ok: true, balance: balance - amount };
  }
}
```

## Construction

You don't construct actors yourself — the runtime does. The base constructor wires `this.ctx` and `this.env`, so a subclass that doesn't need init logic can omit its constructor entirely.

```ts theme={null}
class MyActor extends StatefulActor<Env> {
  // no constructor needed — this.ctx and this.env are wired by the base
}
```

If you do need one-shot init (preload state, set up an initial alarm), override the constructor and call `ctx.blockConcurrencyWhile` — see [Actor Context](/docs/edge-compute/stateful-actors/api-reference/context).

## Dispatch Rules

* **Public methods are RPC-callable** from a stub — declare them `async` (every stub call is a `Promise` on the caller's side regardless).
* Methods whose names start with `_` are internal helpers and are **not** RPC-exposed — the runtime rejects the call.
* The `_` prefix is the only opt-out. TypeScript's `private` keyword is erased at runtime and does **not** stop remote calls; name internal helpers with a leading `_`.
* `fetch(req)`, `alarm(info)`, the constructor, and methods defined on `StatefulActor` itself (not your subclass) are special and not auto-RPC.
* **Methods have a wall-clock budget** (30s by default). A call that exceeds it fails with `ActorMethodTimeoutError` — see [Errors](/docs/edge-compute/stateful-actors/api-reference/errors).

## `alarm(alarmInfo)`

Optional alarm handler. Override to handle scheduled work. The base implementation is a no-op.

```ts theme={null}
async alarm(info: AlarmInfo): Promise<void> {
  // at-least-once delivery — be idempotent
  // info.retryCount is 0 on first delivery; info.isRetry is true on retries
}
```

See [Alarms](/docs/edge-compute/stateful-actors/alarms) for the delivery contract and retry policy.

## `fetch(req)`

Optional HTTP-style entry. The base default returns `404`. Override if you want callers to reach the actor over a raw `Request` instead of RPC methods:

```ts theme={null}
async fetch(req: Request): Promise<Response> {
  return new Response("hello from " + this.ctx.id);
}
```

Callable from a binding as `env.BINDING.idFromName(name).fetch(req)`.

## Related

* [Actor Context](/docs/edge-compute/stateful-actors/api-reference/context) — `this.ctx`: identity, storage, init
* [Actor Storage](/docs/edge-compute/stateful-actors/api-reference/storage) — `this.ctx.storage`
* [Configuration](/docs/edge-compute/stateful-actors/api-reference/configuration) — the `telnyx.toml` actor block
