Account and workspace API access

Read identity, usage and credits, set the workspace model policy, manage webhooks and provider connections over the API, and see what stays in the web app.

Updated

Creative work goes through the session API and the twelve tools. Account and workspace administration — identity, usage and credits, the workspace model policy, webhooks, provider connections, and personal settings — goes through a few /v1 routes and the older operations the service still serves at POST /api/v1/ops/{name}. This page lists exactly what you can reach with a credential, what scope each call needs, and what stays in the web app.

What you can reach

AreaCallsScope
IdentityGET /v1/identity; operations identity.me, workspace.inspectread
Usage and creditsread of wm://credits and wm://receipt/{id}; operations credits.balance, credits.history, credits.activity, credits.holds, credits.inspect, credits.receipts, credits.budgets, credits.ratesread
Plansoperations billing.plans, billing.entitlements, billing.reviews (read); billing.checkout (write)as listed
Workspace model policyGET /v1/workspace/policy (read); PUT /v1/workspace/policy (write, owners and admins)as listed
Webhooks/v1/webhooks/endpoints/**, /v1/webhooks/deliveries/**read to view, write to change
Provider connectionsoperations connections.list, connections.inspect (read); connections.create, connections.enrollment, connections.test, connections.revoke (write)as listed
Personal settingsoperations account.profile.inspect, account.settings.inspect, preferences.me (read); account.profile.save, account.settings.save, preferences.save (write)as listed
Notificationsoperations notifications.list, notifications.inspect, notifications.preferences.inspect (read); notifications.read, notifications.preferences.save (write)as listed
Supportoperations support.list, support.inspect, support.preview (read); support.submit, support.retry (write)as listed
Data exportoperations data.exports.list, data.exports.inspect (read); data.exports.create, data.exports.revoke (write)as listed
Help, docs and blogoperations content.search, content.inspect, content.versions; also GET /api/content/articles/{slug} without a credentialread

What stays in the web app

These are not reachable with a developer credential or an OAuth app:

  • Members, roles and invitations. Inviting, changing a member's role, transferring ownership and renaming a workspace need a signed-in, password-authenticated browser session. A developer credential or OAuth token is refused.
  • Developer credentials. Create, replace and revoke them in Connections › Developer setup. See Client credentials and provider keys.
  • Provider keys. A key is entered only on the private enrollment page. connections.enrollment returns a one-use link to that page; the key never travels through the API.
  • Sign-in, consent, passwords, recovery codes and legal agreements. These stay in their own browser flows. Never put a password, recovery code or provider key in an API or MCP request.
  • Staff consoles. Publishing review, finance, support administration, moderation and infrastructure tools are separate and not reachable through these calls.

Roles and what they mean for API access

RoleEffect on API access
OwnerFull administration, including the workspace model policy
AdminSame API administration as an owner; can create workspace provider connections
MemberUses the workspace with the scopes its credentials carry
ViewerRead only: a viewer's session carries only read

A developer credential or OAuth app acts with at most admin authority, and only when the person who created it is an administrator. Membership alone doesn't grant access to existing creative work. Read more in Keep account and workspace access clear.

Check identity

GET /v1/identity answers who a credential is:

curl --fail-with-body --header "Authorization: Bearer $WAVEMAKER_KEY" \
  https://api.wavemaker.io/v1/identity
# → 200 {"ok": true, "data": {"schema": "wmcore.identity/1", "workspace": "...", "subject": "...",
#        "credential": "...", "kind": "api_key", "mode": "live", "scopes": ["read", "run", "write"],
#        "projects": null, "expires_at": 1793000000.0}, ...}

kind is api_key for a developer credential and oauth for an app sign-in. mode is live, or test for a test workspace. workspace.inspect adds the workspace's execution policy and admission settings.

Usage and credits

  • read of wm://credits returns the balance in microcredits. 1 credit is 1,000,000 microcredits.
  • Each finished session turn links a receipt (wm://receipt/{id}) with its settled cost; read it for the breakdown.
  • credits.history lists credit movements, each marked added, charged, refunded, reserved, returned or restricted. Page with offset and limit.
  • credits.activity filters workspace activity by date, project, job, model, payer and state. Its totals cover every matching record; a final_charge of null means pending, not zero.
  • credits.receipts exports usage with frozen prices and observed units. Pending observations are not settled charges.
  • credits.holds lists current reservations, and credits.budgets lists spending caps and what remains under them.
curl --fail-with-body --header "Authorization: Bearer $WAVEMAKER_KEY" \
  --json '{"limit": 20, "newest_first": true}' \
  https://api.wavemaker.io/api/v1/ops/credits.history
# → 200 {"schema": "wmlab.result/1", "ok": true, "data": {"items": [...], "offset": 0,
#        "next_offset": 20, "total": 134}, "error": null}

billing.checkout with a plan_hash from billing.plans and a request_id creates a hosted checkout and returns its url for a person to complete in the browser. Retry with the same request_id if the outcome is uncertain. Completing the redirect doesn't grant credits by itself; credits arrive when payment is confirmed. See Credits and Plans.

Workspace model policy

The workspace policy limits which models and routes any call in the workspace may use. It is enforced on generate and edit, for every member, credential and agent.

curl --fail-with-body --header "Authorization: Bearer $WAVEMAKER_KEY" \
  https://api.wavemaker.io/v1/workspace/policy
# → 200 {"ok": true, "data": {"revision": 3, "allow": [], "block": [{"kind": "vendor", "value": "xai"}]}, ...}

To change it, send the whole document with the revision you read:

curl --fail-with-body --header "Authorization: Bearer $WAVEMAKER_KEY" -X PUT \
  --json '{"expected_revision": 3, "allow": [{"kind": "licence_class", "value": "commercial"}], "block": []}' \
  https://api.wavemaker.io/v1/workspace/policy
# → 200 {"ok": true, "data": {"revision": 4, "allow": [...], "block": []}, ...}
  • Each item is {kind, value}. kind is route, model, vendor, licence_class (commercial, non_commercial, territory_limited or partner_api) or content_class (permissive).
  • block: a call using any matching route, model, vendor or class is refused.
  • allow: once it names items of a kind, every fact of that kind must be on the list.
  • Each list holds at most 200 items, and each value at most 200 characters.
  • A call outside the policy is refused workspace_policy_refused (403) with the offending item. Wavemaker never substitutes another model.
  • A stale expected_revision is refused conflict (409): read again and reapply your change.
  • Saving needs write and owner or admin authority; anyone else gets scope_denied. Every save is audited.

Webhooks

Webhooks push session milestones and other workspace events to your HTTPS endpoint.

Method and pathPurpose
POST /v1/webhooks/endpointsCreate an endpoint: {url, events[], description}; returns its secret once (201)
GET /v1/webhooks/endpoints, GET /v1/webhooks/endpoints/{id}List or read endpoints
PATCH /v1/webhooks/endpoints/{id}Change url, events, enabled or description, with expected_revision
POST /v1/webhooks/endpoints/{id}/rotateIssue a new secret; the old one keeps signing for 24 hours
POST /v1/webhooks/endpoints/{id}/testSend a test event
DELETE /v1/webhooks/endpoints/{id}Remove an endpoint
GET /v1/webhooks/deliveries, GET /v1/webhooks/deliveries/{id}Read the delivery log
POST /v1/webhooks/deliveries/{id}/retrySend one more attempt for a failed delivery
  • events takes exact types such as turn.completed, families such as turn.*, or *.
  • The URL must be public HTTPS with no credentials, query or fragment, at most 500 characters. Private, loopback and localhost addresses are refused, and redirects are never followed.
  • A workspace has at most 20 endpoints. Each attempt waits up to 10 seconds for your answer; a 2xx counts as delivered.
  • rotate returns the new secret once, as create does.
  • Any other answer, or no answer, is retried after 30 seconds, 2 minutes, 10 minutes, 30 minutes, 2 hours and 6 hours, then marked failed. Only a failed delivery can be retried by hand; the retry is one more attempt with the same delivery id.
  • Each request carries Wavemaker-Signature: t={unix},v1={hex}, Wavemaker-Event and Wavemaker-Delivery. Each v1 is HMAC-SHA256 over {t}.{raw body} with your secret; during a rotation the header carries two v1 values. Deduplicate by delivery_id.
  • Unknown request fields are refused invalid_request with details.path.

Provider connections

The connections.* operations manage bring-your-own provider keys without ever carrying the key itself.

  • connections.create makes the connection record. visibility defaults to personal; only an administrator can create a workspace connection.
  • connections.enrollment with {id, version} returns a one-use link to the private key page. It expires after 10 minutes.
  • connections.test with {id, version} runs a read-only access check and stores the result in readiness.state: ready, denied, unavailable, offline or credential_invalid, or unsupported for a provider with no check. A connection never checked reads untested. Tests of one connection must be at least five seconds apart (connection_rate_limited).
  • connections.revoke deletes the stored key. Provider work already dispatched may still incur cost.
  • The hosted agent's delegated credentials can't create, enroll, test or revoke connections.

See Client credentials and provider keys for what a saved key pays for.

Personal settings, notifications, support and exports

These operations act on you as a person, not on the workspace:

  • They need a credential tied to your enrolled personal account. A credential without one is refused personal_identity_unestablished.
  • A delegated agent's credential is refused forbidden: "Use your own account to manage personal settings".
  • Profile and settings saves take the revision you last read and a request_id. A stale revision is a conflict: read again and reconcile instead of overwriting.
  • data.exports.create prepares a portable archive you own. A workspace export also needs a current owner. Repeating the same request_id resumes the same export.
  • support.submit opens a case in the in-app support channel. Call support.preview first and send its preview_digest with your message (3 to 2,000 characters) and a request_id. Don't include secrets in the message.
curl --fail-with-body --header "Authorization: Bearer $WAVEMAKER_KEY" \
  --json '{"revision": 0, "request_id": "my-settings-1", "timezone": "America/New_York"}' \
  https://api.wavemaker.io/api/v1/ops/account.settings.save

Calling older operations

RouteBody
POST /api/v1/ops/{name}The arguments object
POST /api/v1/operations/{name}{"arguments": {...}}
GET /api/v1/operationsNone; returns the whole older catalog (needs read)

Replies use the older envelope {schema: "wmlab.result/1", ok, data, error}, with error as {code, message, details}.

Status and codeMeaning
401 unauthorizedMissing or invalid credential, or one without the operation's scope; details name the required_scopes
403 forbiddenThe credential has the scope but not the authority, for example a delegated agent changing personal settings
404 resource_missingThe thing named doesn't exist in this workspace
404 with no envelope/ops/{name} with a name outside the catalog
422 request_invalidThe arguments don't match the operation's schema
429 quota_exceededToo many requests; wait retry_after_seconds
501 operation_not_portedThe name is in the catalog but this service doesn't answer it; it won't be added back
503 service_busy or release_drainingBack off for retry_after_seconds, then retry
  • Each operation needs its own exact scope; there is no hierarchy between scopes.
  • GET /api/v1/operations lists served and unserved operations alike. Every agents.*, productions.*, jobs.*, compute.*, creative.* and capabilities.* operation, and models.list, answers 501. Use the tools and the session API for that work.
  • In the Python client, call an operation with call("workspace.inspect") or its typed method workspace_inspect(). The TypeScript client uses call("workspace.inspect", {}), and the Go client has a typed method per operation, such as WorkspaceInspect. See Python, TypeScript and Go clients.

Help, documentation and blog content

content.search returns paginated metadata for published articles. content.inspect with a slug, and optionally a revision, returns the full body. content.versions pages an article's public history. Drafts and archived articles are not returned. The public route GET /api/content/articles/{slug} needs no credential.

Related guidance