Get or Create Actor
Return the actor with the given name and key, creating it if it does not exist. This is the HTTP equivalent of client.actor.getOrCreate(key).
The response includes created, which is true when this call created the actor. A sleeping actor is woken. Without key, a new actor is created every time. Gateway endpoints can perform the same lookup inline with the rvt-* selector parameters, so you only need this endpoint when you want the actor_id up front. A namespace token needs a grant on actor with create.
PUT https://rivet.example.com/actors
Examples
curl -X PUT "https://rivet.example.com/actors?namespace=$RIVET_NAMESPACE" \
-H "Authorization: Bearer $RIVET_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "counter",
"key": "my-counter",
"runner_name_selector": "default"
}'
import { createClient } from "rivetkit/client";
import type { registry } from "./index";
const client = createClient<typeof registry>(process.env.RIVET_ENDPOINT);
// getOrCreate() returns a handle immediately. The PUT /actors call happens
// lazily when the handle is first used, or when you call resolve().
const counter = client.counter.getOrCreate(["my-counter"]);
const actorId = await counter.resolve();
console.log(actorId);
Authentication
Send the admin token, or a namespace token from Create Token whose grants cover the request, as a bearer token in the Authorization header. The x-rivet-token header is also accepted. Routes with a namespace query parameter use the default namespace when it is omitted. See Authentication.
Query Parameters
| Name | Type | Required | Description |
|---|---|---|---|
namespace | string | No | Name of the namespace to operate in. Defaults to default. |
Request Body
Content type: application/json.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name of the actor as registered in your RivetKit registry. 1 to 64 bytes. |
key | string | null | No | Key identifying this actor within its name. Multi-part keys are joined with /, see Actor Keys. |
input | string | null | No | Input passed to the actor if this request creates it, encoded as standard base64 (not base64url). |
runner_name_selector | string | null | No | Node pool that runs the actor. Defaults to default. |
Responses
200
The existing or created actor.
| Field | Type | Description |
|---|---|---|
actor | object | |
actor.actor_id | string | Unique ID of the actor. |
actor.name | string | Actor name as registered in your RivetKit registry. |
actor.key | string | Actor key. Multi-part keys are joined with /, see Actor Keys. An empty string for an actor without a key. |
actor.namespace | string | Name of the namespace the actor belongs to. |
actor.runner_name_selector | string | Node pool the actor runs in. |
actor.create_ts | integer | When the actor was created, in Unix milliseconds. |
actor.start_ts | integer | null | When the actor first started. Not recorded by this version, so always null. |
actor.pending_allocation_ts | integer | null | When the actor started waiting for a node. Not recorded by this version, so always null. |
actor.connectable_ts | integer | null | When the actor last became connectable. Not recorded by this version, so always null. |
actor.sleep_ts | integer | null | When the actor went to sleep. Not recorded by this version, so always null. |
actor.reschedule_ts | integer | null | When the actor will next try to allocate. Not recorded by this version, so always null. |
actor.destroy_ts | integer | null | When the actor was destroyed, in Unix milliseconds. Only set in listings that include destroyed actors; otherwise null. |
created | boolean | true if this request created the actor, false if it already existed. |
{
"actor": {
"actor_id": "d97pbq1nyqxw1w5qdwz0iirbqiblh2",
"name": "my-actor",
"key": "my-key",
"namespace": "my-namespace",
"runner_name_selector": "default",
"create_ts": 1700000000000,
"start_ts": null,
"pending_allocation_ts": null,
"connectable_ts": null,
"sleep_ts": null,
"reschedule_ts": null,
"destroy_ts": null
},
"created": false
}
400
actor.invalid_name: name is empty or longer than 64 bytes. actor.invalid_key: key is longer than 1024 bytes. actor.invalid_key_encoding: key is not in canonical slash-separated form. actor.key_owned_elsewhere: another datacenter owns the key. envoy.invalid_pool_name: runner_name_selector is not a valid pool name. envoy.invalid_namespace_name: the namespace value is not a DNS label of 1 to 63 lowercase letters, digits and hyphens.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "actor",
"code": "invalid_name",
"message": "Actor name must be 1 to 64 bytes."
}
401
auth.invalid_token: the request carries no token, or the token is not valid. auth.token_expired: the token has expired.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "auth",
"code": "invalid_token",
"message": "Authentication token is invalid."
}
403
auth.insufficient_permissions: the token’s grants do not cover this request.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "auth",
"code": "insufficient_permissions",
"message": "Insufficient permissions to access this resource."
}
404
namespace.not_found: the namespace does not exist.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "namespace",
"code": "not_found",
"message": "The namespace does not exist."
}
415
The request is missing the Content-Type: application/json header. Returned as plain text.
Content type: text/plain.
422
The JSON body does not match the request schema, for example a missing required field, a wrong type or an unknown field where unknown fields are rejected. Returned as plain text.
Content type: text/plain.
500
core.internal_error: an unexpected failure, including input that is not valid base64 and a create that did not finish within 30 seconds.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "core",
"code": "internal_error",
"message": "An internal error occurred"
}
503
auth.verification_unavailable: token verification keys are temporarily unavailable. Retry the request.
| Field | Type | Description |
|---|---|---|
group | string | Error group, for example actor. |
code | string | Error code within the group, for example not_found. |
message | string | Human-readable error message. |
metadata | any | Extra details. Only present on some errors raised while authenticating or authorizing the request. |
{
"group": "auth",
"code": "verification_unavailable",
"message": "The server could not verify the authentication token because verification keys are temporarily unavailable. Retry the request."
}