subscribeflow 1.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- subscribeflow-1.0.4/.gitignore +36 -0
- subscribeflow-1.0.4/PKG-INFO +457 -0
- subscribeflow-1.0.4/README.md +422 -0
- subscribeflow-1.0.4/pyproject.toml +78 -0
- subscribeflow-1.0.4/src/subscribeflow/__init__.py +70 -0
- subscribeflow-1.0.4/src/subscribeflow/client.py +1760 -0
- subscribeflow-1.0.4/src/subscribeflow/exceptions.py +107 -0
- subscribeflow-1.0.4/src/subscribeflow/mcp/__init__.py +21 -0
- subscribeflow-1.0.4/src/subscribeflow/mcp/server.py +779 -0
- subscribeflow-1.0.4/src/subscribeflow/mcp/tools.py +1390 -0
- subscribeflow-1.0.4/src/subscribeflow/models.py +498 -0
- subscribeflow-1.0.4/src/subscribeflow/py.typed +0 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
uv.lock
|
|
3
|
+
|
|
4
|
+
# Python
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
*$py.class
|
|
8
|
+
*.so
|
|
9
|
+
.Python
|
|
10
|
+
build/
|
|
11
|
+
develop-eggs/
|
|
12
|
+
dist/
|
|
13
|
+
downloads/
|
|
14
|
+
eggs/
|
|
15
|
+
.eggs/
|
|
16
|
+
lib/
|
|
17
|
+
lib64/
|
|
18
|
+
parts/
|
|
19
|
+
sdist/
|
|
20
|
+
var/
|
|
21
|
+
wheels/
|
|
22
|
+
*.egg-info/
|
|
23
|
+
.installed.cfg
|
|
24
|
+
*.egg
|
|
25
|
+
|
|
26
|
+
# Testing
|
|
27
|
+
.pytest_cache/
|
|
28
|
+
.coverage
|
|
29
|
+
htmlcov/
|
|
30
|
+
.mypy_cache/
|
|
31
|
+
|
|
32
|
+
# IDE
|
|
33
|
+
.idea/
|
|
34
|
+
.vscode/
|
|
35
|
+
*.swp
|
|
36
|
+
*.swo
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: subscribeflow
|
|
3
|
+
Version: 1.0.4
|
|
4
|
+
Summary: Python SDK for SubscribeFlow API - Email subscription management
|
|
5
|
+
Project-URL: Homepage, https://subscribeflow.net
|
|
6
|
+
Project-URL: Documentation, https://docs.subscribeflow.net/guides/sdk-setup
|
|
7
|
+
Project-URL: Repository, https://github.com/talent-factory/subscribe-flow
|
|
8
|
+
Project-URL: Issues, https://github.com/talent-factory/subscribe-flow/issues
|
|
9
|
+
Author-email: SubscribeFlow Team <support@subscribeflow.net>
|
|
10
|
+
License: MIT
|
|
11
|
+
Keywords: api,email,newsletter,sdk,subscribeflow,subscription
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Communications :: Email
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Typing :: Typed
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Requires-Dist: httpx>=0.27.0
|
|
25
|
+
Requires-Dist: pydantic[email]>=2.0.0
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: mypy>=1.10.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-httpx>=0.30.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.6.0; extra == 'dev'
|
|
32
|
+
Provides-Extra: mcp
|
|
33
|
+
Requires-Dist: mcp>=1.0.0; extra == 'mcp'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
36
|
+
# subscribeflow
|
|
37
|
+
|
|
38
|
+
Official Python SDK for the SubscribeFlow API.
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
### Von GitHub (Empfohlen)
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Basis-SDK
|
|
46
|
+
pip install "subscribeflow @ git+https://github.com/talent-factory/subscribe-flow.git#subdirectory=sdk/python"
|
|
47
|
+
|
|
48
|
+
# Mit MCP-Server (für Claude Desktop/Code Integration)
|
|
49
|
+
pip install "subscribeflow[mcp] @ git+https://github.com/talent-factory/subscribe-flow.git#subdirectory=sdk/python"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
In `requirements.txt`:
|
|
53
|
+
```
|
|
54
|
+
subscribeflow @ git+https://github.com/talent-factory/subscribe-flow.git#subdirectory=sdk/python
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Mit MCP-Support:
|
|
58
|
+
```
|
|
59
|
+
subscribeflow[mcp] @ git+https://github.com/talent-factory/subscribe-flow.git#subdirectory=sdk/python
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
In `pyproject.toml` (uv/Poetry/PDM):
|
|
63
|
+
```toml
|
|
64
|
+
[project.dependencies]
|
|
65
|
+
subscribeflow = { git = "https://github.com/talent-factory/subscribe-flow.git", subdirectory = "sdk/python" }
|
|
66
|
+
|
|
67
|
+
# Oder mit MCP-Support
|
|
68
|
+
subscribeflow = { git = "https://github.com/talent-factory/subscribe-flow.git", subdirectory = "sdk/python", extras = ["mcp"] }
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Lokale Entwicklung
|
|
72
|
+
|
|
73
|
+
Für parallele Entwicklung von SDK und Anwendung:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Editable Install (Änderungen am SDK wirken sofort)
|
|
77
|
+
pip install -e /pfad/zu/subscribeflow/sdk/python
|
|
78
|
+
|
|
79
|
+
# Mit uv (schneller)
|
|
80
|
+
uv pip install -e /pfad/zu/subscribeflow/sdk/python
|
|
81
|
+
|
|
82
|
+
# Oder relativ vom Projekt
|
|
83
|
+
pip install -e ../subscribeflow/sdk/python
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
In `pyproject.toml` für lokale Entwicklung:
|
|
87
|
+
```toml
|
|
88
|
+
[tool.poetry.dependencies]
|
|
89
|
+
subscribeflow = { path = "../subscribeflow/sdk/python", develop = true }
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Quick Start
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
import asyncio
|
|
96
|
+
from subscribeflow import SubscribeFlowClient
|
|
97
|
+
|
|
98
|
+
async def main():
|
|
99
|
+
async with SubscribeFlowClient(api_key="sf_live_xxx") as client:
|
|
100
|
+
# Create a subscriber
|
|
101
|
+
subscriber = await client.subscribers.create(
|
|
102
|
+
email="user@example.com",
|
|
103
|
+
tags=["newsletter", "product-updates"],
|
|
104
|
+
metadata={"source": "website"},
|
|
105
|
+
)
|
|
106
|
+
print(f"Created subscriber: {subscriber.id}")
|
|
107
|
+
|
|
108
|
+
asyncio.run(main())
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Usage
|
|
112
|
+
|
|
113
|
+
### Subscribers
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
# List subscribers
|
|
117
|
+
result = await client.subscribers.list(
|
|
118
|
+
limit=50,
|
|
119
|
+
status="active",
|
|
120
|
+
)
|
|
121
|
+
for subscriber in result:
|
|
122
|
+
print(subscriber.email)
|
|
123
|
+
|
|
124
|
+
# Pagination
|
|
125
|
+
while result.next_cursor:
|
|
126
|
+
result = await client.subscribers.list(cursor=result.next_cursor)
|
|
127
|
+
for subscriber in result:
|
|
128
|
+
print(subscriber.email)
|
|
129
|
+
|
|
130
|
+
# Get a subscriber
|
|
131
|
+
subscriber = await client.subscribers.get("subscriber-id")
|
|
132
|
+
|
|
133
|
+
# Update a subscriber
|
|
134
|
+
updated = await client.subscribers.update(
|
|
135
|
+
"subscriber-id",
|
|
136
|
+
metadata={"plan": "premium"},
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# Delete a subscriber
|
|
140
|
+
await client.subscribers.delete("subscriber-id")
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Tags
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
# Create a tag
|
|
147
|
+
tag = await client.tags.create(
|
|
148
|
+
name="Product Updates",
|
|
149
|
+
description="Get notified about new features",
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
# List tags
|
|
153
|
+
tags = await client.tags.list()
|
|
154
|
+
for tag in tags:
|
|
155
|
+
print(f"{tag.name}: {tag.subscriber_count} subscribers")
|
|
156
|
+
|
|
157
|
+
# Update a tag
|
|
158
|
+
await client.tags.update(
|
|
159
|
+
"tag-id",
|
|
160
|
+
description="Updated description",
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Delete a tag
|
|
164
|
+
await client.tags.delete("tag-id")
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Templates
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
# Create an email template
|
|
171
|
+
template = await client.templates.create(
|
|
172
|
+
name="Welcome Email",
|
|
173
|
+
subject="Welcome to {{company}}!",
|
|
174
|
+
mjml_content="<mjml><mj-body>...</mj-body></mjml>",
|
|
175
|
+
category="transactional",
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
# List templates
|
|
179
|
+
templates = await client.templates.list(category="transactional")
|
|
180
|
+
|
|
181
|
+
# Get a template by slug
|
|
182
|
+
template = await client.templates.get("welcome-email")
|
|
183
|
+
|
|
184
|
+
# Preview a template with variables
|
|
185
|
+
preview = await client.templates.preview(
|
|
186
|
+
"template-id",
|
|
187
|
+
variables={"company": "Acme Inc"},
|
|
188
|
+
)
|
|
189
|
+
print(preview.html)
|
|
190
|
+
|
|
191
|
+
# Update a template
|
|
192
|
+
await client.templates.update("template-id", subject="New Subject")
|
|
193
|
+
|
|
194
|
+
# Delete a template
|
|
195
|
+
await client.templates.delete("template-id")
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Email Send
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
# Send a transactional email
|
|
202
|
+
result = await client.emails.send(
|
|
203
|
+
template_slug="welcome-email",
|
|
204
|
+
to="user@example.com",
|
|
205
|
+
variables={"company": "Acme Inc"},
|
|
206
|
+
idempotency_key="unique-key-123",
|
|
207
|
+
)
|
|
208
|
+
print(f"Email queued: {result.id} (status: {result.status})")
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Campaigns
|
|
212
|
+
|
|
213
|
+
```python
|
|
214
|
+
from subscribeflow.models import TagFilter
|
|
215
|
+
|
|
216
|
+
# Create a campaign
|
|
217
|
+
campaign = await client.campaigns.create(
|
|
218
|
+
name="February Newsletter",
|
|
219
|
+
template_id="template-uuid",
|
|
220
|
+
tag_filter={"include_tags": ["newsletter"], "match": "any"},
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
# List campaigns
|
|
224
|
+
campaigns = await client.campaigns.list(status="draft")
|
|
225
|
+
|
|
226
|
+
# Preview recipient count
|
|
227
|
+
count = await client.campaigns.count_recipients(include_tags=["newsletter"])
|
|
228
|
+
print(f"Will be sent to {count} subscribers")
|
|
229
|
+
|
|
230
|
+
# Send the campaign
|
|
231
|
+
result = await client.campaigns.send("campaign-id")
|
|
232
|
+
print(f"Sending to {result.total_recipients} recipients")
|
|
233
|
+
|
|
234
|
+
# Cancel a running campaign
|
|
235
|
+
await client.campaigns.cancel("campaign-id")
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Email Triggers
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
# Create an event-based trigger
|
|
242
|
+
trigger = await client.triggers.create(
|
|
243
|
+
event_type="subscriber.created",
|
|
244
|
+
template_id="welcome-template-uuid",
|
|
245
|
+
description="Send welcome email on signup",
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
# List triggers
|
|
249
|
+
triggers = await client.triggers.list()
|
|
250
|
+
|
|
251
|
+
# Update a trigger
|
|
252
|
+
await client.triggers.update("trigger-id", is_active=False)
|
|
253
|
+
|
|
254
|
+
# Delete a trigger
|
|
255
|
+
await client.triggers.delete("trigger-id")
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Webhooks
|
|
259
|
+
|
|
260
|
+
```python
|
|
261
|
+
# Create a webhook endpoint
|
|
262
|
+
webhook = await client.webhooks.create(
|
|
263
|
+
url="https://your-app.com/webhooks/subscribeflow",
|
|
264
|
+
events=["subscriber.created", "tag.subscribed"],
|
|
265
|
+
description="Main webhook endpoint",
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# Store the signing secret securely!
|
|
269
|
+
print(f"Signing secret: {webhook.secret}")
|
|
270
|
+
|
|
271
|
+
# List webhook endpoints
|
|
272
|
+
webhooks = await client.webhooks.list()
|
|
273
|
+
|
|
274
|
+
# Update a webhook
|
|
275
|
+
await client.webhooks.update(
|
|
276
|
+
"webhook-id",
|
|
277
|
+
events=["subscriber.created", "subscriber.deleted"],
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
# Test a webhook
|
|
281
|
+
result = await client.webhooks.test("webhook-id")
|
|
282
|
+
if result.success:
|
|
283
|
+
print(f"Webhook working! Response time: {result.response_time_ms}ms")
|
|
284
|
+
else:
|
|
285
|
+
print(f"Webhook failed: {result.error}")
|
|
286
|
+
|
|
287
|
+
# Rotate signing secret
|
|
288
|
+
new_webhook = await client.webhooks.regenerate_secret("webhook-id")
|
|
289
|
+
print(f"New secret: {new_webhook.secret}")
|
|
290
|
+
|
|
291
|
+
# View delivery history
|
|
292
|
+
deliveries = await client.webhooks.list_deliveries("webhook-id")
|
|
293
|
+
for d in deliveries:
|
|
294
|
+
print(f"{d.event_type}: {d.status}")
|
|
295
|
+
|
|
296
|
+
# Get delivery statistics
|
|
297
|
+
stats = await client.webhooks.get_stats("webhook-id")
|
|
298
|
+
print(f"Success rate: {stats.success_rate}%")
|
|
299
|
+
|
|
300
|
+
# Retry a failed delivery
|
|
301
|
+
await client.webhooks.retry_delivery("webhook-id", "delivery-id")
|
|
302
|
+
|
|
303
|
+
# Delete a webhook
|
|
304
|
+
await client.webhooks.delete("webhook-id")
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### Preference Center
|
|
308
|
+
|
|
309
|
+
```python
|
|
310
|
+
# Generate a preference center token for a subscriber
|
|
311
|
+
token_response = await client.subscribers.generate_token("subscriber-id")
|
|
312
|
+
|
|
313
|
+
# Access the preference center with the token
|
|
314
|
+
pref_center = client.preference_center(token_response.token)
|
|
315
|
+
|
|
316
|
+
# Get subscriber preferences and available tags
|
|
317
|
+
info = await pref_center.get_preferences()
|
|
318
|
+
print(f"Subscribed to: {len(info.subscribed_tags)} tags")
|
|
319
|
+
print(f"Available: {len(info.available_tags)} tags")
|
|
320
|
+
|
|
321
|
+
# Subscribe to a tag
|
|
322
|
+
result = await pref_center.subscribe_tag("tag-id")
|
|
323
|
+
|
|
324
|
+
# Unsubscribe from a tag
|
|
325
|
+
result = await pref_center.unsubscribe_tag("tag-id")
|
|
326
|
+
|
|
327
|
+
# Export all data (DSGVO)
|
|
328
|
+
export = await pref_center.export_data()
|
|
329
|
+
|
|
330
|
+
# Delete account (DSGVO)
|
|
331
|
+
await pref_center.delete_account()
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Error Handling
|
|
335
|
+
|
|
336
|
+
```python
|
|
337
|
+
from subscribeflow import (
|
|
338
|
+
SubscribeFlowClient,
|
|
339
|
+
SubscribeFlowError,
|
|
340
|
+
AuthenticationError,
|
|
341
|
+
AuthorizationError,
|
|
342
|
+
NotFoundError,
|
|
343
|
+
ValidationError,
|
|
344
|
+
RateLimitError,
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
try:
|
|
348
|
+
subscriber = await client.subscribers.get("non-existent-id")
|
|
349
|
+
except NotFoundError as e:
|
|
350
|
+
print(f"Subscriber not found: {e.detail}")
|
|
351
|
+
except ValidationError as e:
|
|
352
|
+
print(f"Validation failed: {e.detail}")
|
|
353
|
+
for error in e.errors:
|
|
354
|
+
print(f" - {error['loc']}: {error['msg']}")
|
|
355
|
+
except RateLimitError as e:
|
|
356
|
+
print("Rate limit exceeded, please retry later")
|
|
357
|
+
except AuthenticationError as e:
|
|
358
|
+
print("Invalid API key")
|
|
359
|
+
except AuthorizationError as e:
|
|
360
|
+
print("Insufficient permissions")
|
|
361
|
+
except SubscribeFlowError as e:
|
|
362
|
+
print(f"API error ({e.status}): {e.detail}")
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## Configuration
|
|
366
|
+
|
|
367
|
+
```python
|
|
368
|
+
client = SubscribeFlowClient(
|
|
369
|
+
# Required: Your API key
|
|
370
|
+
api_key="sf_live_xxx",
|
|
371
|
+
|
|
372
|
+
# Optional: API base URL (default: https://api.subscribeflow.net)
|
|
373
|
+
# Note: SDK appends /api/v1/... to the base URL automatically
|
|
374
|
+
base_url="https://api.subscribeflow.net",
|
|
375
|
+
|
|
376
|
+
# Optional: Request timeout in seconds (default: 30)
|
|
377
|
+
timeout=30.0,
|
|
378
|
+
)
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### Lokale API-Instanz
|
|
382
|
+
|
|
383
|
+
Für Entwicklung gegen eine lokale SubscribeFlow-Instanz:
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
client = SubscribeFlowClient(
|
|
387
|
+
api_key="sf_dev_xxx",
|
|
388
|
+
base_url="http://localhost:8000", # SDK fügt /api/v1/... automatisch hinzu
|
|
389
|
+
)
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## MCP Server (Claude Integration)
|
|
393
|
+
|
|
394
|
+
Das SDK enthält einen MCP-Server für die Integration mit Claude Desktop und Claude Code.
|
|
395
|
+
|
|
396
|
+
### Quick Start
|
|
397
|
+
|
|
398
|
+
**Claude Desktop/Code Konfiguration** (`claude_desktop_config.json`):
|
|
399
|
+
|
|
400
|
+
```json
|
|
401
|
+
{
|
|
402
|
+
"mcpServers": {
|
|
403
|
+
"subscribeflow": {
|
|
404
|
+
"command": "uv",
|
|
405
|
+
"args": [
|
|
406
|
+
"--directory", "/pfad/zu/subscribe-flow/sdk/python",
|
|
407
|
+
"run", "subscribeflow-mcp"
|
|
408
|
+
],
|
|
409
|
+
"env": {
|
|
410
|
+
"SUBSCRIBEFLOW_API_KEY": "sf_live_xxx"
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
Nach der Konfiguration kannst du Claude bitten:
|
|
418
|
+
|
|
419
|
+
> "Füge user@example.com zum Newsletter hinzu"
|
|
420
|
+
|
|
421
|
+
Claude ruft automatisch die passenden Tools auf.
|
|
422
|
+
|
|
423
|
+
**Vollständige Dokumentation:** [MCP Integration Guide](https://docs.subscribeflow.net/guides/mcp-integration)
|
|
424
|
+
|
|
425
|
+
## Without Context Manager
|
|
426
|
+
|
|
427
|
+
If you prefer not to use the async context manager, remember to close the client:
|
|
428
|
+
|
|
429
|
+
```python
|
|
430
|
+
client = SubscribeFlowClient(api_key="sf_live_xxx")
|
|
431
|
+
try:
|
|
432
|
+
subscriber = await client.subscribers.get("id")
|
|
433
|
+
finally:
|
|
434
|
+
await client.close()
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
## Type Hints
|
|
438
|
+
|
|
439
|
+
This SDK is fully typed and works great with mypy and other type checkers:
|
|
440
|
+
|
|
441
|
+
```python
|
|
442
|
+
from subscribeflow import SubscribeFlowClient, Subscriber, Tag
|
|
443
|
+
|
|
444
|
+
async def get_active_subscribers(client: SubscribeFlowClient) -> list[Subscriber]:
|
|
445
|
+
result = await client.subscribers.list(status="active")
|
|
446
|
+
return result.items
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
## Links
|
|
450
|
+
|
|
451
|
+
- [API Documentation](https://docs.subscribeflow.net/reference/api)
|
|
452
|
+
- [Getting Started Guide](https://docs.subscribeflow.net/getting-started)
|
|
453
|
+
- [Webhook Integration](https://docs.subscribeflow.net/guides/webhooks)
|
|
454
|
+
|
|
455
|
+
## License
|
|
456
|
+
|
|
457
|
+
MIT
|