Members
Roles, removals and monthly run limits.
Change a member's role
/api/v1/org/members/{userId}Makes a member an admin or a member. Never the owner, and never the person the key acts as. Demoting an admin also revokes the org keys they made and the open invites they sent, at once, each with a line in the trail, so a later re-promotion never brings a key back and an invite never outlives its sender's seat.
An API key carrying the scope named here, or a signed-in session.
- Scope
members:write- Key kinds
- Organization
- Access
- The caller must administer the organization.
Required and optional fields, allowed values and errors, as the page shows them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
userId | Path | string (uuid) | Required | The member's user id: id from GET /api/v1/org. |
Request body
The new role.
Fields (1)
| Field | Type | Required | Description |
|---|---|---|---|
role | string | Required | member or admin. |
{
"role": "admin"
}Examples
curl -X PATCH "https://liviamatch.com/api/v1/org/members/e1a5c8d2-6f37-4b94-a0c1-8d2e4f6a9b13" \
-H "Authorization: Bearer $LIVIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"role": "admin"
}'Responses
The member and their role now.
{
"data": {
"id": "e1a5c8d2-6f37-4b94-a0c1-8d2e4f6a9b13",
"email": "dev@hearthandkey.example",
"role": "admin"
}
}Fields (4)
| Field | Type | Description |
|---|---|---|
data | object | |
data.id | string (uuid) | |
data.email | string | |
data.role | string |
Errors
| Status | Code | When |
|---|---|---|
| 403 | forbidden | The caller does not administer the org. |
| 404 | not-found | No such member in the org. |
| 400 | invalid | The body failed validation; issues names each field. |
| 400 | invalid-json | The body is empty or not JSON. |
| 409 | owner-protected | The member is the org's owner. |
| 409 | own-membership | The member is the person the key acts as. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal
Remove a member
/api/v1/org/members/{userId}Removes a member from the org. They land in a new org of their own and keep their account, and the org keys they made and the open invites they sent are revoked. Never the owner, and never the person the key acts as.
An API key carrying the scope named here, or a signed-in session.
- Scope
members:write- Key kinds
- Organization
- Access
- The caller must administer the organization.
Required and optional fields, allowed values and errors, as the page shows them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
userId | Path | string (uuid) | Required | The member's user id: id from GET /api/v1/org. |
Examples
curl -X DELETE "https://liviamatch.com/api/v1/org/members/e1a5c8d2-6f37-4b94-a0c1-8d2e4f6a9b13" \
-H "Authorization: Bearer $LIVIA_API_KEY"Responses
The member is removed.
{
"data": {
"id": "e1a5c8d2-6f37-4b94-a0c1-8d2e4f6a9b13",
"removed": true
}
}Fields (3)
| Field | Type | Description |
|---|---|---|
data | object | |
data.id | string (uuid) | |
data.removed | true |
Errors
| Status | Code | When |
|---|---|---|
| 403 | forbidden | The caller does not administer the org. |
| 404 | not-found | No such member in the org. |
| 409 | owner-protected | The member is the org's owner. |
| 409 | own-membership | The member is the person the key acts as. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal
Set a member's monthly limit
/api/v1/org/members/{userId}/limitCaps the matches one person may start each month inside the org's pool. A limit is a cap, never a reservation. null clears the person's own limit so they follow the org default. A whole number from 0 to 100,000; 0 pauses them.
An API key carrying the scope named here, or a signed-in session.
- Scope
org:write- Key kinds
- Organization
- Access
- The caller must administer the organization.
Required and optional fields, allowed values and errors, as the page shows them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
userId | Path | string (uuid) | Required | The member's user id: id from GET /api/v1/org. |
Request body
The limit.
Fields (1)
| Field | Type | Required | Description |
|---|---|---|---|
monthlyMatches | number | null | Required | Matches a month for this person: a whole number from 0 to 100000, or null to follow the org default. 0 pauses them. |
{
"monthlyMatches": 25
}Examples
curl -X PUT "https://liviamatch.com/api/v1/org/members/e1a5c8d2-6f37-4b94-a0c1-8d2e4f6a9b13/limit" \
-H "Authorization: Bearer $LIVIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"monthlyMatches": 25
}'Responses
The limit that applies to them now, and where it comes from.
{
"data": {
"id": "e1a5c8d2-6f37-4b94-a0c1-8d2e4f6a9b13",
"email": "dev@hearthandkey.example",
"limit": 25,
"limitFrom": "person"
}
}Fields (5)
| Field | Type | Description |
|---|---|---|
data | object | |
data.id | string (uuid) | |
data.email | string | |
data.limit | integer | null | Matches a month that apply to them; null is none. |
data.limitFrom | string | Whether the limit is their own or the org default. |
Errors
| Status | Code | When |
|---|---|---|
| 403 | forbidden | The caller does not administer the org. |
| 404 | not-found | No such member in the org. |
| 400 | invalid | The body failed validation; issues names each field. |
| 400 | invalid-json | The body is empty or not JSON. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal
Move runs between members
/api/v1/org/limit-movesTakes runs off one member's monthly limit and adds them to another's, in one step. Both must already have a limit of their own. The giver cannot give more than they have left this month. Send the count as runs; the old name matches is still taken, and a body naming both with different counts is refused.
An API key carrying the scope named here, or a signed-in session.
- Scope
org:write- Key kinds
- Organization
- Access
- The caller must administer the organization.
Required and optional fields, allowed values and errors, as the page shows them.
Request body
Who gives, who receives, and how many.
Fields (4)
| Field | Type | Required | Description |
|---|---|---|---|
from | string | Required | The id of the member who gives runs up. |
to | string | Required | The id of the member who receives them. Not the same person. |
runs | number | Optional | How many runs: a whole number from 1 to 100000, no more than the giver has left this month. |
matches | number | Optional | The old name for runs. Send one or the other; if you send both, they must agree. |
{
"from": "3a8d1e47-9c52-4b0f-a6d3-5e7b2c9f1a04",
"to": "e1a5c8d2-6f37-4b94-a0c1-8d2e4f6a9b13",
"runs": 5
}Examples
curl -X POST "https://liviamatch.com/api/v1/org/limit-moves" \
-H "Authorization: Bearer $LIVIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "3a8d1e47-9c52-4b0f-a6d3-5e7b2c9f1a04",
"to": "e1a5c8d2-6f37-4b94-a0c1-8d2e4f6a9b13",
"runs": 5
}'Responses
Each side's limit now.
{
"data": {
"matches": 5,
"runs": 5,
"from": {
"id": "3a8d1e47-9c52-4b0f-a6d3-5e7b2c9f1a04",
"limit": 55
},
"to": {
"id": "e1a5c8d2-6f37-4b94-a0c1-8d2e4f6a9b13",
"limit": 25
}
}
}Fields (9)
| Field | Type | Description |
|---|---|---|
data | object | |
data.matches | integer | The old name for runs, with the same count. |
data.runs | integer | How many runs moved. |
data.from | object | |
data.from.id | string (uuid) | |
data.from.limit | integer | |
data.to | object | |
data.to.id | string (uuid) | |
data.to.limit | integer |
Errors
| Status | Code | When |
|---|---|---|
| 403 | forbidden | The caller does not administer the org. |
| 400 | invalid | The body failed validation; issues names each field. |
| 400 | invalid-json | The body is empty or not JSON. |
| 404 | not-found | One of the two is not a member of the org. |
| 409 | no-limit | One of the two has no limit of their own to move. |
| 409 | over-room | The giver has fewer unused runs this month than asked. |
Any call of this kind can also answer401 unauthenticated401 invalid-api-key403 insufficient-scope429 rate-limited429 monthly-cap-reached500 internal