• Partitioned access: Users, templates, and activity are scoped to a single workspace.
  • Usage tracking: See envelopes sent per workspace for clean reporting.
  • Security by design: No cross-workspace exposure of documents or data.
This makes it simple to give every customer or team their own private signing environment while you manage everything through the same API.

Core Endpoints

Core endpoints (see the API reference for full details):
  • POST /workspaces — create a workspace
  • GET /workspaces/{workspace_id} — retrieve workspace details
  • PUT /workspaces/{workspace_id} — update workspace
  • GET /workspaces — list workspaces (pagination)
You can also find dedicated reference pages under api-reference/workspaces:
  • api-reference/workspaces/create-workspace
  • api-reference/workspaces/get-workspace
  • api-reference/workspaces/list-workspaces
  • api-reference/workspaces/update-workspace
Authentication All requests must include an Authorization header using your API key:
Authorization: Bearer YOUR_API_KEY
Note: never expose your primary API key to end-user browsers. For per-workspace operations that need to be initiated from the frontend, call your backend which holds the key.

Create a workspace

Endpoint: POST /workspacess Required body: { "name": "string" } Example (curl):
curl -X POST "https://api.firma.dev/v1/workspacess" \
  -H "Authorization: Bearer $FIRMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Acme Corp Workspace" }'
Successful response (201) returns the Workspaces resource with id, name, and timestamps. Example shape:
{
  "id": "team_123",
  "name": "Acme Corp Workspace",
  "protected": false,
  "created_date": "2025-09-04T12:00:00Z",
  "updated_date": "2025-09-04T12:00:00Z"
}
Server example — Node (fetch):
import fetch from 'node-fetch'

export async function createWorkspace(name) {
  const resp = await fetch('https://api.firma.dev/v1/workspaces', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ name })
  })
  if (!resp.ok) throw new Error(`create workspace failed: ${resp.status}`)
  return resp.json()
}
Server example — Python (requests):
import os
import requests

def create_workspace(name):
    url = 'https://api.firma.dev/v1/workspaces'
    resp = requests.post(url, headers={
        'Authorization': f"Bearer {os.environ['FIRMA_API_KEY']}",
        'Content-Type': 'application/json'
    }, json={ 'name': name })
    resp.raise_for_status()
    return resp.json()

Retrieve a workspace

Endpoint: GET /workspaces/{workspace_id} Example (curl):
curl "https://api.firma.dev/v1/workspaces/workspace_123" \
  -H "Authorization: Bearer $FIRMA_API_KEY"
Response: the Workspace resource (see example above).

Update a workspace

Endpoint: PUT /workspaces/{workspace_id} — full resource replacement. Required body same as CreateWorkspace (e.g., { "name": "New name" }). Example (curl):
curl -X PUT "https://api.firma.dev/v1/workspaces/workspace_123" \
  -H "Authorization: Bearer $FIRMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Acme Corp - East Coast" }'
Server example — Node (fetch):
export async function updateWorkspace(teamId, name) {
  const resp = await fetch(`https://api.firma.dev/v1/workspaces/${workspaceId}`, {
    method: 'PUT',
    headers: {
      'Authorization': `Bearer ${process.env.FIRMA_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ name })
  })
  if (!resp.ok) throw new Error(`update workspace failed: ${resp.status}`)
  return resp.json()
}

List workspaces

Endpoint: GET /workspaces Supports page and page_size query parameters. Example:
curl "https://api.firma.dev/v1/workspaces?page=1&page_size=20" \
  -H "Authorization: Bearer $FIRMA_API_KEY"
Response shape contains results (array of Workspace) and pagination metadata.

RBAC and API key best practices

  • Use scoped API keys where possible: keep a server-only master API key and create per-workspace API keys for integration partners if your platform supports it.
  • Never return API keys to the browser. For operations initiated by end users, call your backend which performs the API call to Firma.
  • Use idempotency where supported (for endpoints that accept Idempotency-Key) to avoid double-creation from retries.

Edge cases & troubleshooting

  • Duplicate names: workspace names are display-friendly and may not be unique; use the id for programmatic references.
  • Protected workspaces: the protected flag indicates system-owned workspaces that cannot be deleted or modified by normal flows.
  • Rate limits & errors: inspect non-2xx responses for { error, code } and surface meaningful messages to operators.