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

# Introduction

> Author code nodes for your organization entirely through the API

## Overview

The Code API lets you register your own Python code nodes in the Opus marketplace programmatically — the source the node runs, and the typed inputs and outputs it exposes to a workflow.

These endpoints author the code **catalog**: the definition of a code node, shared across your whole organization. Connecting a code node into a workspace so a workflow can run it is a separate, workspace-scoped step done in the Opus app.

## Base URL

All API requests should be made to the following base URL:

```
https://operator.opus.com/api/v1/code
```

## Authentication

All API endpoints require authentication with your Opus API key, sent in the `x-service-key` header.

```text theme={null}
x-service-key: <your_api_key>
```

Your key determines your identity and your organization. Every endpoint here requires the **Code: Full** permission **at organization level** — a workspace-level grant is not sufficient, because a code node authored here belongs to the organization rather than to a workspace.

A request with a missing, invalid, or expired key returns `401`. A key that is not org-scoped, or whose owner lacks **Code: Full** in the organization, returns `403`.

<Note>
  Your API key is a unique, secret credential. Store it securely and never expose it in client-side code.
</Note>

<Warning>
  Your organization must be verified to author code. Unlike some other sections, this is checked before your request is processed — an unverified organization is rejected with `403`, not further down the stack.
</Warning>

## Authoring Flow

Authoring a code node takes a single call. Unlike the [Integrations API](/api-reference/v1-integration/integration-introduction), there is no provider to create first — your organization's code provider is resolved for you.

<Steps>
  <Step title="Create the Code Node">
    `POST /` registers the node under your organization with its source and IO schema. Keep the returned `id`.
  </Step>

  <Step title="Revise It">
    `PATCH /{codeId}` updates any subset of fields. Each call cuts a new code version, so the previous state stays addressable.
  </Step>
</Steps>

<Note>
  There is no `providerId` field anywhere in this section. The organization comes from your API key and the code service resolves that organization's canonical provider itself — accepting one from the caller would allow authoring into another organization's provider. If you send one, it is ignored.
</Note>

## Writing the Source

`sourceCode` is a Python module that must define `main`. It is called with a **single dictionary** holding every declared input, keyed by `variableName`, and must return a dictionary keyed by your declared output names:

```python theme={null}
import re


def main(inputs):
    raw_text = inputs.get("raw_text") or ""

    return {"clean_text": re.sub(r"\s+", " ", raw_text).strip()}
```

<Warning>
  `main` takes one argument, not one parameter per input. A module without a `main`, or one whose `main` expects named parameters, fails at execution with `main(inputs) not defined` or a `TypeError` — neither is caught at authoring time.
</Warning>

Your code runs in the same environment as code authored in the Opus app, with the same curated package set. See [Available Packages](/opus-sdk/available-packages) and the [Opus SDK overview](/opus-sdk/overview).

<Note>
  `Opus` is a reserved name. The SDK object is injected into your module *after* it is imported and before `main` runs, so it is available inside `main` but not at module level — and defining your own `Opus` is rejected with `Opus is a reserved keyword`.
</Note>

### Security scanning

Source is scanned before it is stored. Code importing a blocked module, or using a prohibited construct, is rejected with `400` and a `violations` array naming the line, column and reason:

```json theme={null}
{
  "statusCode": 400,
  "metadata": {
    "violations": [
      { "line": 1, "col": 0, "message": "Blocked import: 'os'" }
    ]
  }
}
```

<Warning>
  The scan covers prohibited patterns, not the whole package whitelist. An import that is merely *not on the list* — rather than explicitly blocked — passes authoring and fails when the node runs. Check [Available Packages](/opus-sdk/available-packages) before you publish.
</Warning>

## Inputs and Outputs

`inputs` and `outputs` describe the code node's signature to the workflow builder. Both are maps keyed by the variable's own `variableName`:

```json theme={null}
{
  "raw_text": {
    "id": "1",
    "variableName": "raw_text",
    "displayName": "Raw Text",
    "allowedTypes": [{ "type": "str" }]
  }
}
```

The key and the `variableName` inside it must match. Each variable needs at least one entry in `allowedTypes`; for composite types, `allowedTypes[].typeDefinition` describes the shape inside.

<Note>
  The field names are camelCase, but a `variableName` **value** is the key your code reads out of the `inputs` dictionary, so it follows Python convention rather than ours. `"variableName": "raw_text"` pairs with `inputs.get("raw_text")`.
</Note>

## Usage Notes

* **Nothing is workspace-scoped.** A code node authored here belongs to your organization. No workspace id is accepted anywhere in this section.
* **A code node is not runnable on create.** It is a catalog entry until it is connected into a workspace.
* **Update replaces, it does not merge.** `sourceCode`, `inputs` and `outputs` are swapped wholesale by `PATCH`. Send the complete value you want stored.
* **`sourceCode` is capped in bytes, not characters.** The limit is measured on the UTF-8 encoding, so non-ASCII source counts for more than its length — see [Limits](#limits).
* **Every write cuts a version.** Both endpoints return a `versionId`, and it differs on every successful call.
* **There is no read or delete.** This section authors only; it has no `GET` and no `DELETE`. Store the `id` returned by create — you cannot look it up again here.

## Limits

| Field | Limit |
| - | - |
| `name` | 255 characters |
| `description` | 2,048 characters |
| `icon` | 65,535 characters |
| `sourceCode` | 262,144 bytes, UTF-8 encoded |
| `categories` | 5 entries |
| `inputs` / `outputs` | 100 variables, 512KB JSON-encoded |
| `allowedTypes` | 1–11 entries per variable |
| `tags` / `options` / `nonEditableFields` | 20 entries each |

## Available Endpoints

<CardGroup cols={2}>
  <Card title="Create a Code Node" icon="code" href="/api-reference/v1-code/create-code">
    Register a Python code node with its source and IO schema
  </Card>

  <Card title="Update a Code Node" icon="pen-to-square" href="/api-reference/v1-code/update-code">
    Revise a code node your organization owns, cutting a new version
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.