Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.nevermined.app/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Every Nevermined account can belong to one or more organizations — first-class workspaces with their own members, agents, plans, and billing. The Payments SDK exposes three building blocks for working with them from your code:
  • List your memberships — every organization you’re an active member of, with your role in each.
  • Publish into a specific workspace — when you register an agent, plan, or API key, tell the SDK which workspace should own it.
  • Read the activity feed — paginated events for everything happening in an organization (member changes, customers, subscriptions, webhook deliveries).
These map to a small, focused surface on payments.organizations and a single optional organizationId argument on the publish methods you already use.
Workspace selection is transported by the X-Current-Org-Id header. The backend resolves it in priority order: route path parameter → this header → the API key’s organization tag → your most-recent active membership → personal account. Pinning a workspace via the SDK is the same control your webapp’s workspace switcher uses.

List the organizations you belong to

Use this to drive a workspace picker in your own tools, or to confirm where a publish will land before sending it.
import { Payments } from '@nevermined-io/payments'

const payments = Payments.getInstance({
  nvmApiKey: process.env.NVM_API_KEY!,
  environment: 'sandbox',
})

const memberships = await payments.organizations.getMyMemberships()

for (const m of memberships) {
  console.log(`${m.orgName} (${m.orgType}) — ${m.role}${m.isAdmin ? ' (admin)' : ''}`)
}
A typical response (a Premium org and an Enterprise one):
[
  {
    "orgId": "org-3f9a...",
    "orgName": "Acme Robotics",
    "role": "Admin",
    "orgType": "Premium",
    "isAdmin": true,
    "hasSubscriptionHistory": true
  },
  {
    "orgId": "org-7d11...",
    "orgName": "Beta Labs",
    "role": "Member",
    "orgType": "Enterprise",
    "isAdmin": false,
    "hasSubscriptionHistory": true
  }
]
If you have no active memberships the list is empty — you’re operating as a personal account.

Publish into a specific organization

Two ways to choose where a published agent, plan, or API key lands. Pick whichever fits the calling code. Pass organizationId (TypeScript) or organization_id= (Python) to the publish method. The SDK sends X-Current-Org-Id for that call only — your instance-level workspace is untouched.
// Publish a single agent into Acme Robotics, without leaving Acme as your active workspace.
const { agentId } = await payments.agents.registerAgent(
  { name: 'Legal Assistant', tags: ['legal', 'rag'] },
  {
    authType: 'bearer',
    endpoints: [{ POST: 'https://api.example.com/legal/tasks' }],
  },
  [planId],
  { organizationId: 'org-3f9a...' },
)
The same organizationId / organization_id option works on registerAgentAndPlan / register_agent_and_plan and on the plan-registration helpers (registerPlan, registerCreditsPlan, registerTimePlan and their register_*_plan Python equivalents).

Pin a workspace for the whole session

Set the organization once and every subsequent call from this Payments instance — including all sub-APIs (agents, plans, requests, …) — uses it.
payments.setOrganizationId('org-3f9a...')

// All of these now land in Acme Robotics:
await payments.agents.registerAgent(metadata, api, [planId])
await payments.plans.registerCreditsPlan(planMetadata, price, credits)

// Clear the pin when you're done — falls back to personal / API-key default.
payments.setOrganizationId(null)
You can also pin from the constructor:
const payments = Payments.getInstance({
  nvmApiKey: process.env.NVM_API_KEY!,
  environment: 'sandbox',
  organizationId: 'org-3f9a...',
})
Targeting an organization you’re not a member of (or an inactive membership) is rejected by the backend with a 403. The SDK surfaces this as a PaymentsError.

Read the organization activity feed

Paginated events for member changes, customer additions, subscription transitions, and webhook deliveries. Only members of the organization can read it; the backend enforces a Premium+ entitlement.
import { OrganizationActivityEventType } from '@nevermined-io/payments'

const page = await payments.organizations.getOrganizationActivity(
  'org-3f9a...',
  {
    eventType: OrganizationActivityEventType.MemberInvited,
    from: '2026-05-01T00:00:00Z',
    to: '2026-05-31T23:59:59Z',
    page: 1,
    limit: 25,
  },
)

console.log(`${page.total} matching events`)
for (const event of page.items) {
  console.log(event.occurredAt, event.eventType, event.subject.kind, event.subject.id)
}
All filters are optional. The eventType filter accepts a single value or a list of values (sent as a comma-separated list); limit is the page size (backend cap: 200). The known event types you can filter on:
Event typeEmitted when
member.invited / member.joinedAn admin invites a teammate; the invitee accepts
member.role_changedA member’s role flips between Admin and Member
member.deactivated / member.reactivated / member.removedMembership lifecycle transitions
invitation.revoked / invitation.expiredPending invitation lifecycle
agent.created / plan.created / plan.purchasedResource lifecycle inside the org
customer.added / customer.blocked / customer.unblockedExternal customer lifecycle
subscription.upgraded / subscription.downgraded / subscription.canceled / subscription.lapsedTier subscription transitions on the org
webhook.delivered / webhook.failedWebhook delivery outcomes (status in metadata)
New event types are accepted without an SDK upgrade — the eventType field is a plain string in both SDKs. Each event also carries a subject: { kind, id, …extras } payload describing the resource it’s about (e.g. invitations include role + email, members include role + userId, subscriptions include tier).

How workspace context is resolved

When the backend handles an authenticated request, it picks the active organization in this order — the first match wins:
1

Route path

If the URL itself includes :orgId (for example /organizations/{orgId}/activity), that organization is used directly.
2

X-Current-Org-Id header

Set by the SDK from your pin or per-call override. The backend validates that you’re an active member of the requested org before honoring it.
3

API key tag

If your NVM API key was minted scoped to a specific organization, that scope is applied.
4

Fallback membership

Your most-recent active membership — preserves backwards compatibility for single-org callers that don’t set anything explicitly.
5

Personal account

No active membership → resources you publish are owned by your personal account.
The SDK never picks a workspace silently — if you don’t set one, the backend’s fallback rules apply.

Organizations on Nevermined

Concepts, tiers, and the webapp surface for organization owners.

Quickstart — TypeScript

Set up the SDK and publish your first agent.

Quickstart — Python

Set up the Python SDK and publish your first agent.

Payment Models

Fixed, usage-based, and outcome-based pricing patterns.