On this page
Guides / Workspace variables

Workspace variables

Store workspace values and secrets — like the token for an HTTP Function — and discover your CRM's fields.

met.variables stores two things belonging to the workspace: value variables (configuration and secrets, such as the token for an external API) and the definitions of your CRM's custom fields. The first needs the variables:write scope to write; the second lets you discover which keys a contact accepts.

const met = new Met(key, { workspaceId });

Value variables

A variable is a namevalue pair that lives in the workspace. set() upserts by name — creating or updating depending on whether it exists — which is the most convenient form.

await met.variables.set('my_api_token', 'sk_live_...', { encrypted: true });

const vars = await met.variables.list();   // never returns secrets in the clear

Mark encrypted: true for tokens and secrets: the value is stored encrypted and list() no longer returns it in the clear. If you prefer explicit operations by id, you have create, update and delete:

const v = await met.variables.create({
  name: 'greeting',
  value: 'Hello!',
  description: 'Default text',
});                                         // POST /variables (variables:write)

await met.variables.update(v.id, { value: 'Welcome!' });
await met.variables.delete(v.id);

set() runs a list() to find the name; if you are going to write many variables in a row, go straight to create/update with the id you already have.

Token → HTTP Function

The headline use case: an HTTP Function resolves its authentication token by variable name, not in the raw. You store the token once and the Function references it with auth_workspace_variable; Meteor sends it as Authorization: Bearer <value> when calling your endpoint.

// 1. Store the secret (encrypted)
await met.variables.set('my_api_token', 'sk_live_...', { encrypted: true });

// 2. The Function references it by name
await met.functions.create({
  name: 'check_price',
  description: 'Looks up a product price in the external API',
  http: {
    url: 'https://api.example.com/price',
    method: 'POST',
    auth_workspace_variable: 'my_api_token',
  },
});

That way the token is never written into the Function's definition. To rotate it, a single set() with the same name replaces it and every Function using it is up to date.

CRM field definitions

A contact's custom fields live in its data under the bare key (stage, amount); system fields carry a $ ($name, $status). To find out which keys exist and which options a select accepts, discover the catalog:

const defs = await met.variables.fieldDefinitions();   // variables:read
const stages = defs.find((d) => d.field_key === 'stage')?.options ?? [];

await met.contacts.update(42, { data: { stage: stages[0] } });

Each definition carries field_key, label, type (text · number · select · currency · date · …) and options. You can also manage them from code:

const field = await met.variables.createFieldDefinition({
  field_key: 'stage',
  label: 'Stage',
  type: 'select',
  options: ['New', 'Contacted', 'Closed'],
});

await met.variables.updateFieldDefinition(field.id, { options: [...field.options, 'Lost'] });
await met.variables.deleteFieldDefinition(field.id);

field_key and type cannot be edited: changing them would break the values already stored on your contacts. You only adjust label, description and options.

To read and write those values on each contact, see Contacts (CRM).