Memberstack Admin API Skill
This skill provides guidance for interacting with the Memberstack Admin API. It covers two core domains: Member management and Data Tables.
Quick Start
All requests require an API key passed via header:
x-api-key: YOUR_API_KEY
Base URL: https://admin.memberstack.com
Data Tables endpoints use the /v2/ prefix; Member endpoints do not.
API Key Handling
Never ask the user for their API key directly in the conversation. API keys are sensitive credentials and should never appear in chat, code snippets shown to the user, or be hardcoded in source files. Instead:
- Store the key in a
.env file (e.g., MEMBERSTACK_API_KEY=sk_...) and read it via process.env.MEMBERSTACK_API_KEY (Node) or os.environ["MEMBERSTACK_API_KEY"] (Python).
- Alternatively, use the platform's secrets/environment variable management (e.g., Vercel Environment Variables, Cloudflare Secrets, AWS Secrets Manager).
- When generating code, always reference the key from an environment variable, never use a placeholder that looks like a real key.
- If the user pastes an API key in the chat, remind them to rotate it and move it to a
.env file or secret store instead.
When to Read Reference Files
This skill bundles the full API reference docs. Read them based on what the user needs:
Member operations (list, get, create, update, delete, add/remove plans):
Read references/memberstack-member-actions.md
Data Tables (list tables, get table schema, create/update/delete/query records):
Read references/memberstack-data-tables.md
If the task involves both members and data tables, read both files.
API Overview
Members API
Endpoints for managing members, their profiles, plan connections, and metadata.
| Action |
Method |
Endpoint |
| List members |
GET |
/members |
| Get member |
GET |
/members/:id_or_email |
| Create member |
POST |
/members |
| Update member |
PATCH |
/members/:id |
| Delete member |
DELETE |
/members/:id |
| Add free plan |
POST |
/members/:id/add-plan |
| Remove free plan |
POST |
/members/:id/remove-plan |
Key concepts:
- Member IDs start with
mem_, plan IDs with pln_, connection IDs with con_
- Members can be looked up by ID or URL-encoded email
- Pagination uses cursor-based
after + limit (max 200)
- Members have
customFields, metaData, json, permissions, and planConnections
Data Tables API
Endpoints for managing structured data with typed fields, relationships, and querying.
| Action |
Method |
Endpoint |
| List tables |
GET |
/v2/data-tables |
| Get table |
GET |
/v2/data-tables/:tableKey |
| Create record |
POST |
/v2/data-tables/:tableKey/records |
| Update record |
PUT |
/v2/data-tables/:tableKey/records/:recordId |
| Delete record |
DELETE |
/v2/data-tables/:tableKey/records/:recordId |
| Query records |
POST |
/v2/data-tables/:tableKey/records/query |
Key concepts:
- Tables are referenced by key (e.g.,
products) or ID (e.g., tbl_...)
- Records hold data as key-value pairs matching field definitions
- Querying supports
findMany and findUnique with rich filtering (equals, contains, gt, lt, in, logical operators AND/OR/NOT)
- Pagination via
take (max 100), skip, or cursor-based after
- Field types include TEXT, NUMBER, DECIMAL, BOOLEAN, DATE, EMAIL, URL, REFERENCE, and MEMBER_REFERENCE variants
Common Patterns
Paginating Through All Members
let allMembers = [];
let cursor = undefined;
let hasMore = true;
while (hasMore) {
const params = new URLSearchParams({ limit: '200' });
if (cursor) params.set('after', cursor);
const res = await fetch(`https://admin.memberstack.com/members?${params}`, {
headers: { 'x-api-key': API_KEY }
});
const json = await res.json();
allMembers.push(...json.data);
hasMore = json.hasNextPage;
cursor = json.endCursor;
}
Querying Data Records with Filters
const res = await fetch(
'https://admin.memberstack.com/v2/data-tables/products/records/query',
{
method: 'POST',
headers: {
'x-api-key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: {
findMany: {
where: {
AND: [
{ price: { gte: 10 } },
{ inStock: { equals: true } }
]
},
orderBy: { price: 'asc' },
take: 50
}
}
})
}
);
Creating a Member with a Plan
const res = await fetch('https://admin.memberstack.com/members', {
method: 'POST',
headers: {
'x-api-key': API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
email: 'user@example.com',
password: 'securePassword123',
plans: [{ planId: 'pln_abc123' }],
customFields: { firstName: 'Jane', country: 'Australia' }
})
});
Error Handling
The API returns errors as JSON with code and message fields. Common status codes:
- 400: Bad request (missing required fields, invalid formats, empty data)
- 404: Resource not found (wrong table key, nonexistent member/record)
Always check for these and surface clear messages to the user.
Tips
- When deleting members, consider setting
deleteStripeCustomer and cancelStripeSubscriptions to avoid orphaned billing records.
- Use
findUnique with where.id when you know the exact record ID — it's simpler and returns a single record.
- The
_count option in findMany is useful for getting totals without fetching all records.
select and include are mutually exclusive in queries — use include to expand relationships, select to limit returned fields.
1---2name: memberstack-admin-api3description: Work with the Memberstack Admin API to manage members, plans, and data tables. Use this skill whenever the user mentions Memberstack, member management via API, Memberstack data tables, or wants to build integrations that create/read/update/delete members or data records in Memberstack. Also trigger when the user asks about Memberstack API endpoints, authentication, pagination, querying records, or connecting plans to members — even if they don't say "Memberstack" explicitly but reference concepts like plan connections, member metadata, or admin member APIs that align with Memberstack's domain.4license: MIT5---67# Memberstack Admin API Skill89This skill provides guidance for interacting with the Memberstack Admin API. It covers two core domains: **Member management** and **Data Tables**.1011## Quick Start1213All requests require an API key passed via header:1415```16x-api-key: YOUR_API_KEY17```1819Base URL: `https://admin.memberstack.com`2021Data Tables endpoints use the `/v2/` prefix; Member endpoints do not.2223## API Key Handling2425Never ask the user for their API key directly in the conversation. API keys are sensitive credentials and should never appear in chat, code snippets shown to the user, or be hardcoded in source files. Instead:2627- Store the key in a `.env` file (e.g., `MEMBERSTACK_API_KEY=sk_...`) and read it via `process.env.MEMBERSTACK_API_KEY` (Node) or `os.environ["MEMBERSTACK_API_KEY"]` (Python).28- Alternatively, use the platform's secrets/environment variable management (e.g., Vercel Environment Variables, Cloudflare Secrets, AWS Secrets Manager).29- When generating code, always reference the key from an environment variable, never use a placeholder that looks like a real key.30- If the user pastes an API key in the chat, remind them to rotate it and move it to a `.env` file or secret store instead.3132## When to Read Reference Files3334This skill bundles the full API reference docs. Read them based on what the user needs:3536- **Member operations** (list, get, create, update, delete, add/remove plans):37 Read `references/memberstack-member-actions.md`3839- **Data Tables** (list tables, get table schema, create/update/delete/query records):40 Read `references/memberstack-data-tables.md`4142If the task involves both members and data tables, read both files.4344## API Overview4546### Members API4748Endpoints for managing members, their profiles, plan connections, and metadata.4950| Action | Method | Endpoint |51|--------|--------|----------|52| List members | GET | `/members` |53| Get member | GET | `/members/:id_or_email` |54| Create member | POST | `/members` |55| Update member | PATCH | `/members/:id` |56| Delete member | DELETE | `/members/:id` |57| Add free plan | POST | `/members/:id/add-plan` |58| Remove free plan | POST | `/members/:id/remove-plan` |5960Key concepts:61- Member IDs start with `mem_`, plan IDs with `pln_`, connection IDs with `con_`62- Members can be looked up by ID or URL-encoded email63- Pagination uses cursor-based `after` + `limit` (max 200)64- Members have `customFields`, `metaData`, `json`, `permissions`, and `planConnections`6566### Data Tables API6768Endpoints for managing structured data with typed fields, relationships, and querying.6970| Action | Method | Endpoint |71|--------|--------|----------|72| List tables | GET | `/v2/data-tables` |73| Get table | GET | `/v2/data-tables/:tableKey` |74| Create record | POST | `/v2/data-tables/:tableKey/records` |75| Update record | PUT | `/v2/data-tables/:tableKey/records/:recordId` |76| Delete record | DELETE | `/v2/data-tables/:tableKey/records/:recordId` |77| Query records | POST | `/v2/data-tables/:tableKey/records/query` |7879Key concepts:80- Tables are referenced by key (e.g., `products`) or ID (e.g., `tbl_...`)81- Records hold data as key-value pairs matching field definitions82- Querying supports `findMany` and `findUnique` with rich filtering (`equals`, `contains`, `gt`, `lt`, `in`, logical operators `AND`/`OR`/`NOT`)83- Pagination via `take` (max 100), `skip`, or cursor-based `after`84- Field types include TEXT, NUMBER, DECIMAL, BOOLEAN, DATE, EMAIL, URL, REFERENCE, and MEMBER_REFERENCE variants8586## Common Patterns8788### Paginating Through All Members8990```javascript91let allMembers = [];92let cursor = undefined;93let hasMore = true;9495while (hasMore) {96 const params = new URLSearchParams({ limit: '200' });97 if (cursor) params.set('after', cursor);9899 const res = await fetch(`https://admin.memberstack.com/members?${params}`, {100 headers: { 'x-api-key': API_KEY }101 });102 const json = await res.json();103104 allMembers.push(...json.data);105 hasMore = json.hasNextPage;106 cursor = json.endCursor;107}108```109110### Querying Data Records with Filters111112```javascript113const res = await fetch(114 'https://admin.memberstack.com/v2/data-tables/products/records/query',115 {116 method: 'POST',117 headers: {118 'x-api-key': API_KEY,119 'Content-Type': 'application/json'120 },121 body: JSON.stringify({122 query: {123 findMany: {124 where: {125 AND: [126 { price: { gte: 10 } },127 { inStock: { equals: true } }128 ]129 },130 orderBy: { price: 'asc' },131 take: 50132 }133 }134 })135 }136);137```138139### Creating a Member with a Plan140141```javascript142const res = await fetch('https://admin.memberstack.com/members', {143 method: 'POST',144 headers: {145 'x-api-key': API_KEY,146 'Content-Type': 'application/json'147 },148 body: JSON.stringify({149 email: 'user@example.com',150 password: 'securePassword123',151 plans: [{ planId: 'pln_abc123' }],152 customFields: { firstName: 'Jane', country: 'Australia' }153 })154});155```156157## Error Handling158159The API returns errors as JSON with `code` and `message` fields. Common status codes:160- **400**: Bad request (missing required fields, invalid formats, empty data)161- **404**: Resource not found (wrong table key, nonexistent member/record)162163Always check for these and surface clear messages to the user.164165## Tips166167- When deleting members, consider setting `deleteStripeCustomer` and `cancelStripeSubscriptions` to avoid orphaned billing records.168- Use `findUnique` with `where.id` when you know the exact record ID — it's simpler and returns a single record.169- The `_count` option in `findMany` is useful for getting totals without fetching all records.170- `select` and `include` are mutually exclusive in queries — use `include` to expand relationships, `select` to limit returned fields.