---
title: "Resource shares — API v1 and MCP | Nodea"
description: "Share websites, heartbeats and servers with other accounts through the Nodea API v1. Three-box model, invitations, accept, revoke vs leave and 5 MCP tools."
url: "https://nodea.io/en/api-docs/shares"
lang: "en"
updated: "2026-07-16"
---

# Resource shares — API v1 and MCP | Nodea

> Resource shares let you grant another account read access to a website, heartbeat or server you own. Learn the API v1 endpoints, the three-box model and the MCP tools.

**Share** resources let you grant another registered account read access to a website, heartbeat or server you own. It is the API v1 REST and MCP counterpart of the panel's /app/share/\* page. Sharing is **not gated by a module feature flag** (no features: middleware, exactly like web sharing) — you only need the relevant scope from the alerting group.

Every endpoint lives under the base path /api/v1 (example host: https://app.nodea.io/api/v1). Authentication uses a Passport personal access token in the Authorization: Bearer \<token\> header. The rate limit throttle:api-v1 = 240 requests/min applies. Required scopes: read alerting:read, write alerting:write, delete alerting:delete. Access is checked per row in the controller — a foreign or unknown share id yields **404**.

## API v1

MethodPathScopeDescriptionGET/sharesalerting:readList shares in the three-box model.POST/sharesalerting:writeShare a resource you own with another account.POST/shares/{share}/acceptalerting:writeAccept a pending invitation addressed to you.POST/shares/{share}/declinealerting:writeDecline a pending invitation addressed to you.DELETE/shares/{share}alerting:deleteDelete a share: revoke (as owner) or leave (as recipient).

### GET /shares — the three-box model

The listing is organised into three boxes, mirroring the panel's /sharing page. The box query parameter accepts one of:

- incoming\_pending — invitations addressed to me, awaiting my response (foreign FOREIGN rows with a null accepted\_at).
- incoming\_accepted — shares I accepted from others.
- outbound — invitations I sent (foreign FOREIGN rows on resources I own), together with the recipient.

When you pass box, a single set is returned simple-paginated (per\_page, default 20, max 100; page). **When you omit box**, the endpoint returns all three boxes in one JSON object (keys incoming\_pending, incoming\_accepted, outbound), each capped at per\_page rows — use box to page through a specific set.

curl -s https://app.nodea.io/api/v1/shares?box=incoming\_pending \\ -H "Authorization: Bearer $TOKEN"

Each response row (ShareResource) contains:

- id — the share identifier.
- resource\_type — website, heartbeat or server.
- resource — a compact summary of the shared item (id, name, plus url for websites and ip for servers). It is null if the item was deleted after the share was created.
- status — pending or accepted.
- accepted\_at, created\_at — ISO 8601 timestamps.
- recipient — the account the item is shared with (id, name, email).
- owner — the owner of the underlying resource (or null).

### POST /shares — share a resource

The body requires three fields: resource\_type (enum website | heartbeat | server), resource\_id (the resource id — websites and heartbeats use integer ids, servers use UUIDs) and the email of the invitee (must belong to a registered user).

The resource must be owned by the caller. Unknown and foreign ids collapse into the same **422** error so the endpoint cannot be used to enumerate other tenants' ids. Attempting to share a resource with yourself also returns **422**.

For websites and heartbeats a **pending invitation** is created (a pending share) and a notification sent — unless the recipient auto-accepts shares from the sender (then accepted immediately). Server shares have no handshake and become active at once (accepted\_at is stamped immediately). Success returns **201 Created** with the share representation. Re-sharing an already-shared resource returns **409 Conflict** with code already\_shared. Signed-URL invitation links stay web-only.

curl -s -X POST https://app.nodea.io/api/v1/shares \\ -H "Authorization: Bearer $TOKEN" \\ -H "Content-Type: application/json" \\ -d '{"resource\_type":"website","resource\_id":"42","email":"collab@example.com"}'

### POST /shares/{share}/accept and /decline — the recipient handshake

An invitation can be accepted or declined **only by the recipient** of a pending FOREIGN row addressed to them. Anyone else — including the resource owner — gets a **404** (it is simply not their invitation). accept stamps accepted\_at = now() and returns the updated resource; decline deletes the row and returns **204 No Content** (the owner may send a new invitation later).

curl -s -X POST https://app.nodea.io/api/v1/shares/123/accept \\ -H "Authorization: Bearer $TOKEN"

### DELETE /shares/{share} — revoke vs leave

This endpoint deletes only FOREIGN rows (an OWNER row is the owner's own visibility bookkeeping — deleting it returns **404**). The controller decides the role and meaning of the operation itself:

- **revoke** — if the caller owns the underlying resource, it removes the recipient's access.
- **leave** — if the caller is the recipient of an **accepted** share, they leave it themselves.

A pending invitation is **not** deleted here — use the decline endpoint to reject it. Success returns **204 No Content**. No rights to the row (neither owner nor accepted recipient) yields **404**.

curl -s -X DELETE https://app.nodea.io/api/v1/shares/123 \\ -H "Authorization: Bearer $TOKEN"

### Error codes

CodeMeaning401Missing or invalid access token.403Token lacks the required scope (alerting:read / write / delete).404Unknown or foreign share id — access is checked per row.422Validation error: unknown/foreign resource, sharing with yourself, bad box.

## MCP

The Nodea MCP server exposes five sharing tools. Each enforces the same scope as its REST counterpart. A *read-only* mode never changes state; a *destructive* mode requires an explicit confirm: true so an agent cannot cut off someone's access on a loosely-parsed instruction.

NameScopeModeDescriptionshares-listalerting:readread-onlyList the user's shares with a box marker on each row.share-createalerting:writewrite (idempotent)Share a resource you own with another account by email.share-acceptalerting:writewriteAccept a pending invitation addressed to you.share-declinealerting:writewriteDecline a pending invitation (the owner may send a new one).share-revokealerting:deletedestructive (confirm: true)Revoke (owner) or leave (recipient) an active share.

The share-create tool is idempotent — re-sharing an already-shared resource is a no-op (status: already\_shared). The share-accept and share-decline tools operate only on a pending invitation addressed to the caller; they need no confirmation because nothing irreversible is lost (a declined invitation can be re-sent by the owner). Only share-revoke is marked destructive and **requires** confirm: true.

{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "shares-list", "arguments": { "box": "incoming\_pending", "per\_page": 15 } } }{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "share-create", "arguments": { "resource\_type": "website", "resource\_id": "42", "recipient\_email": "collab@example.com" } } }{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "share-revoke", "arguments": { "id": 123, "confirm": true } } }

## Related

- [Notification Integrations — API v1 and MCP | Nodea](https://nodea.io/en/api-docs/integrations)
- [Notification Groups — API v1 and MCP Tools | Nodea](https://nodea.io/en/api-docs/notification-groups)

---

Languages: [pl](https://nodea.pl/pl/dokumentacja-api/shares.md)  
Site index: [llms.txt](https://nodea.io/en/llms.txt)
