Introduction
# Systeme.io
Access the Systeme.io API with managed OAuth authentication. Manage contacts, tags, courses, communities, and subscriptions.
## Quick Start
```bash # List contacts python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/systeme/api/contacts') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
## Base URL
``` https://gateway.maton.ai/systeme/{native-api-path} ```
Replace `{native-api-path}` with the actual Systeme.io API endpoint path. The gateway proxies requests to `api.systeme.io` and automatically injects your API key.
## Authentication
All requests require the Maton API key in the Authorization header:
``` Authorization: Bearer $MATON_API_KEY ```
**Environment Variable:** Set your API key as `MATON_API_KEY`:
```bash export MATON_API_KEY="YOUR_API_KEY" ```
### Getting Your API Key
1. Sign in or create an account at [maton.ai](https://maton.ai) 2. Go to [maton.ai/settings](https://maton.ai/settings) 3. Copy your API key
## Connection Management
Manage your Systeme.io connections at `https://ctrl.maton.ai`.
### List Connections
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=systeme&status=ACTIVE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
### Create Connection
```bash python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'systeme'}).encode() req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
### Get Connection
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
**Response:** ```json { "connection": { "connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80", "status": "ACTIVE", "creation_time": "2025-12-08T07:20:53.488460Z", "last_updated_time": "2026-01-31T20:03:32.593153Z", "url": "https://connect.maton.ai/?session_token=...", "app": "systeme", "metadata": {} } } ```
Open the returned `url` in a browser to complete OAuth authorization.
### Delete Connection
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
### Specifying Connection
If you have multiple Systeme.io connections, specify which one to use with the `Maton-Connection` header:
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/systeme/api/contacts') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
If omitted, the gateway uses the default (oldest) active connection.
## API Reference
### Contact Operations
#### List Contacts
```bash GET /systeme/api/contacts ```
**Query Parameters:** - `limit` - Number of items per page (10-100, optional) - `startingAfter` - ID of last received item for pagination (optional) - `order` - Sort order: `asc` or `desc` (default: `desc`, optional)
#### Get Contact
```bash GET /systeme/api/contacts/{id} ```
#### Create Contact
```bash POST /systeme/api/contacts Content-Type: application/json
{ "email": "[email protected]", "firstName": "John", "lastName": "Doe", "phoneNumber": "+1234567890", "locale": "en", "fields": [ { "slug": "custom_field_slug", "value": "custom value" } ] } ```
#### Update Contact
```bash PATCH /systeme/api/contacts/{id} Content-Type: application/merge-patch+json
{ "firstName": "Jane", "lastName": "Smith" } ```
#### Delete Contact
```bash DELETE /systeme/api/contacts/{id} ```
### Tag Operations
#### List Tags
```bash GET /systeme/api/tags ```
#### Get Tag
```bash GET /systeme/api/tags/{id} ```
#### Create Tag
```bash POST /systeme/api/tags Content-Type: application/json
{ "name": "VIP Customer" } ```
#### Update Tag
```bash PUT /systeme/api/tags/{id} Content-Type: application/json
{ "name": "Premium Customer" } ```
#### Delete Tag
```bash DELETE /systeme/api/tags/{id} ```
### Contact Tag Operations
#### Assign Tag to Contact
```bash POST /systeme/api/contacts/{id}/tags Content-Type: application/json
{ "tagId": 12345 } ```
#### Remove Tag from Contact
```bash DELETE /systeme/api/contacts/{id}/tags/{tagId} ```
### Contact Field Operations
#### List Contact Fields
```bash GET /systeme/api/contact_fields ```
#### Create Contact Field
```bash POST /systeme/api/contact_fields Content-Type: application/json
{ "name": "Company Name", "slug": "company_name" } ```
#### Update Contact Field
```bash PATCH /systeme/api/contact_fields/{slug} Content-Type: application/merge-patch+json
{ "name": "Organization Name" } ```
#### Delete Contact Field
```bash DELETE /systeme/api/contact_fields/{slug} ```
### Course Operations
#### List Courses
```bash GET /systeme/api/school/courses ```
#### List Enrollments
```bash GET /systeme/api/school/enrollments ```
#### Create Enrollment
```bash POST /systeme/api/school/courses/{courseId}/enrollments Content-Type: application/json
{ "contactId": 12345, "accessType": "full_access" } ```
**Required Fields:** - `contactId` - The ID of the contact to enroll - `accessType` - Access type: `full_access`, `partial_access`, or `dripping_content`
**Note:** If `accessType` is `partial_access`, you must also provide a `modules` array with module IDs.
#### Delete Enrollment
```bash DELETE /systeme/api/school/enrollments/{id} ```
### Community Operations
#### List Communities
```bash GET /systeme/api/community/communities ```
#### List Memberships
```bash GET /systeme/api/community/memberships ```
#### Create Membership
```bash POST /systeme/api/community/communities/{communityId}/memberships Content-Type: application/json
{ "contactId": 12345 } ```
#### Delete Membership
```bash DELETE /systeme/api/community/memberships/{id} ```
### Subscription Operations
#### List Subscriptions
```bash GET /systeme/api/payment/subscriptions ```
#### Cancel Subscription
```bash POST /systeme/api/payment/subscriptions/{id}/cancel ```
## Pagination
Systeme.io uses cursor-based pagination with the following parameters:
```bash GET /systeme/api/contacts?limit=50&startingAfter=12345&order=asc ```
**Parameters:** - `limit` - Number of items per page (10-100) - `startingAfter` - ID of the last item from the previous page - `order` - Sort order: `asc` or `desc` (default: `desc`)
**Response:** ```json { "items": [...], "hasMore": true } ```
When `hasMore` is `true`, use the ID of the last item in `items` as `startingAfter` to get the next page.
## Code Examples
### JavaScript
```javascript const response = await fetch( 'https://gateway.maton.ai/systeme/api/contacts', { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } } ); const data = await response.json(); ```
### Python
```python import os import requests
response = requests.get( 'https://gateway.maton.ai/systeme/api/contacts', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'} ) data = response.json() ```
### Create Contact with Tag
```python import os import requests
# Create contact contact = requests.post( 'https://gateway.maton.ai/systeme/api/contacts', headers={ 'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}', 'Content-Type': 'application/json' }, json={ 'email': '[email protected]', 'firstName': 'New', 'lastName': 'Contact' } ).json()
# Assign tag requests.post( f'https://gateway.maton.ai/systeme/api/contacts/{contact["id"]}/tags', headers={ 'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}', 'Content-Type': 'application/json' }, json={'tagId': 12345} ) ```
## Notes
- Systeme.io uses API key authentication (passed as `X-API-Key` header natively) - The gateway automatically handles auth header transformation - Use `application/merge-patch+json` content type for PATCH requests - Contact, tag, course, and enrollment IDs are numeric integers - Rate limits are enforced via `X-RateLimit-*` headers - Systeme.io validates email domains - only real email addresses with valid MX records are accepted - The subscriptions endpoint (`/api/payment/subscriptions`) may return 404 if payment features are not configured - IMPORTANT: When using curl commands, use `curl -g` when URLs contain brackets to disable glob parsing - IMPORTANT: When piping curl output to `jq` or other commands, environment variables like `$MATON_API_KEY` may not expand correctly in some shell environments
## Error Handling
| Status | Meaning | |--------|---------| | 400 | Missing Systeme.io connection or bad request | | 401 | Invalid or missing Maton API key | | 429 | Rate limited (check `Retry-After` header) | | 4xx/5xx | Passthrough error from Systeme.io API |
### Troubleshooting: API Key Issues
1. Check that the `MATON_API_KEY` environment variable is set:
```bash echo $MATON_API_KEY ```
2. Verify the API key is valid by listing connections:
```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```
### Troubleshooting: Invalid App Name
1. Ensure your URL path starts with `systeme`. For example:
- Correct: `https://gateway.maton.ai/systeme/api/contacts` - Incorrect: `https://gateway.maton.ai/api/contacts`
## Resources
- [Systeme.io API Reference](https://developer.systeme.io/reference) - [Systeme.io API Overview](https://developer.systeme.io/) - [Maton Community](https://discord.com/invite/dBfFAcefs2) - [Maton Support](mailto:[email protected])