Loopfour
API Reference

Workflow Secrets API

Manage write-only secrets scoped to one workflow

Workflow Secrets API

Workflow secrets store encrypted values that belong to a single workflow. Step config can reference them as {{ secrets.KEY }}. The API never returns plaintext or ciphertext; reads return only a masked value.

All endpoints require authentication with x-api-key or a Studio session. API keys need secrets:read for listing and secrets:write for create, rotate, and delete.

List Secrets

GET /api/v1/workflows/:workflowId/secrets

Path Parameters

ParameterTypeDescription
workflowIdstringWorkflow UUID. The workflow must belong to the caller's company.

Response

{
  "success": true,
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "workflowId": "660e8400-e29b-41d4-a716-446655440001",
      "key": "SIGNING_KEY",
      "maskedValue": "••••1234",
      "lastUsedAt": null,
      "createdAt": "2026-06-26T10:00:00.000Z",
      "updatedAt": "2026-06-26T10:00:00.000Z"
    }
  ]
}

maskedValue is built from a stored suffix hint when the value is long enough to keep at least one character hidden; shorter values return only the mask prefix. The read path does not decrypt the value.

Example

curl -X GET "http://localhost:3000/api/v1/workflows/WORKFLOW_ID/secrets" \
  -H "x-api-key: YOUR_API_KEY"

Create Secret

POST /api/v1/workflows/:workflowId/secrets

Request Body

FieldTypeRequiredDescription
keystringYesUpper snake case, starts with a letter, max 64 characters. Example: SIGNING_KEY.
valuestringYesSecret value, 1-8192 characters. Returned only through this write request's side effect, never in the response.

Example Request

{
  "key": "SIGNING_KEY",
  "value": "YOUR_SECRET_VALUE"
}

Response

{
  "success": true,
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "workflowId": "660e8400-e29b-41d4-a716-446655440001",
    "key": "SIGNING_KEY",
    "maskedValue": "••••ALUE",
    "lastUsedAt": null,
    "createdAt": "2026-06-26T10:00:00.000Z",
    "updatedAt": "2026-06-26T10:00:00.000Z"
  }
}

Creating the same key twice for one workflow returns 409 CONFLICT.

Rotate Secret

PUT /api/v1/workflows/:workflowId/secrets/:key

Rotation is write-without-read: submit the replacement value and the API stores a new encrypted value without revealing the previous one.

Request Body

FieldTypeRequiredDescription
valuestringYesReplacement value, 1-8192 characters.

Example

curl -X PUT "http://localhost:3000/api/v1/workflows/WORKFLOW_ID/secrets/SIGNING_KEY" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value":"NEW_SECRET_VALUE"}'

Delete Secret

DELETE /api/v1/workflows/:workflowId/secrets/:key

Response

{
  "success": true,
  "data": {
    "deleted": true
  }
}

Deleting a secret does not rewrite workflow step config. Future runs that still reference {{ secrets.KEY }} fail fast with a missing-secret error until the key is recreated or the workflow is updated.

Errors

StatusCodeWhen
400VALIDATION_ERRORInvalid key format or empty value.
401UNAUTHORIZEDMissing or invalid authentication.
403FORBIDDENAuthenticated caller lacks the required secrets:* scope.
404NOT_FOUNDWorkflow is not owned by the caller's company, or the secret key does not exist.
409CONFLICTSecret key already exists for this workflow.

On this page