@xano/developer-mcp 1.0.35 → 1.0.37

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.
Files changed (33) hide show
  1. package/README.md +21 -4
  2. package/dist/xanoscript.js +40 -5
  3. package/dist/xanoscript.test.js +9 -2
  4. package/dist/xanoscript_docs/README.md +46 -42
  5. package/dist/xanoscript_docs/addons.md +10 -0
  6. package/dist/xanoscript_docs/agents.md +15 -0
  7. package/dist/xanoscript_docs/apis.md +45 -24
  8. package/dist/xanoscript_docs/cheatsheet.md +252 -0
  9. package/dist/xanoscript_docs/database.md +23 -0
  10. package/dist/xanoscript_docs/docs_index.json +241 -0
  11. package/dist/xanoscript_docs/frontend.md +10 -0
  12. package/dist/xanoscript_docs/functions.md +4 -0
  13. package/dist/xanoscript_docs/integrations/cloud-storage.md +142 -0
  14. package/dist/xanoscript_docs/integrations/external-apis.md +201 -0
  15. package/dist/xanoscript_docs/integrations/redis.md +194 -0
  16. package/dist/xanoscript_docs/integrations/search.md +242 -0
  17. package/dist/xanoscript_docs/integrations/utilities.md +331 -0
  18. package/dist/xanoscript_docs/integrations.md +55 -901
  19. package/dist/xanoscript_docs/mcp-servers.md +10 -0
  20. package/dist/xanoscript_docs/performance.md +15 -0
  21. package/dist/xanoscript_docs/quickstart.md +22 -88
  22. package/dist/xanoscript_docs/run.md +10 -0
  23. package/dist/xanoscript_docs/security.md +26 -0
  24. package/dist/xanoscript_docs/streaming.md +10 -0
  25. package/dist/xanoscript_docs/syntax.md +56 -0
  26. package/dist/xanoscript_docs/tables.md +15 -0
  27. package/dist/xanoscript_docs/tasks.md +11 -0
  28. package/dist/xanoscript_docs/tools.md +15 -0
  29. package/dist/xanoscript_docs/triggers.md +57 -192
  30. package/dist/xanoscript_docs/types.md +4 -0
  31. package/dist/xanoscript_docs/{testing.md → unit-testing.md} +15 -3
  32. package/dist/xanoscript_docs/workflow-tests.md +333 -0
  33. package/package.json +1 -1
@@ -6,6 +6,29 @@ applyTo: "function/**/*.xs, api/**/*.xs, task/**/*.xs, tool/**/*.xs"
6
6
 
7
7
  Complete reference for XanoScript database operations.
8
8
 
9
+ > **TL;DR:** Use `db.get` for single record by ID, `db.query` for filtered lists, `db.has` to check existence, `db.add` to insert, `db.edit` for inline updates, `db.patch` for dynamic fields, `db.del` to delete.
10
+
11
+ ## Choosing an Operation
12
+
13
+ ```
14
+ Need to...
15
+ ├── Read data?
16
+ │ ├── Single record by ID? → db.get
17
+ │ ├── Check if exists? → db.has
18
+ │ └── Filtered list? → db.query
19
+ ├── Write data?
20
+ │ ├── New record? → db.add
21
+ │ ├── Update known fields? → db.edit
22
+ │ └── Update dynamic fields? → db.patch
23
+ ├── Delete data?
24
+ │ ├── Single record? → db.del
25
+ │ └── All records? → db.truncate
26
+ └── Complex query?
27
+ ├── Join tables? → db.query with join
28
+ ├── Aggregate? → db.query with evals
29
+ └── Transaction? → db.transaction
30
+ ```
31
+
9
32
  ## Quick Reference
10
33
 
11
34
  | Operation | Purpose | Returns |
@@ -0,0 +1,241 @@
1
+ {
2
+ "version": "1.0.0",
3
+ "description": "Machine-readable index for XanoScript documentation",
4
+
5
+ "topics": {
6
+ "cheatsheet": {
7
+ "file": "cheatsheet.md",
8
+ "purpose": "Quick reference for 20 most common operations",
9
+ "priority": 1,
10
+ "aliases": ["quick", "common", "basics", "start"]
11
+ },
12
+ "quickstart": {
13
+ "file": "quickstart.md",
14
+ "purpose": "Common patterns and mistakes to avoid",
15
+ "priority": 2,
16
+ "aliases": ["start", "getting-started", "patterns", "mistakes"]
17
+ },
18
+ "syntax": {
19
+ "file": "syntax.md",
20
+ "purpose": "Operators, filters, expressions, error handling",
21
+ "priority": 3,
22
+ "aliases": ["filters", "operators", "expressions"]
23
+ },
24
+ "types": {
25
+ "file": "types.md",
26
+ "purpose": "Data types, validation, input blocks",
27
+ "priority": 4,
28
+ "aliases": ["validation", "input", "data-types"]
29
+ },
30
+ "database": {
31
+ "file": "database.md",
32
+ "purpose": "All db.* operations",
33
+ "priority": 5,
34
+ "aliases": ["db", "crud", "query", "sql"]
35
+ },
36
+ "tables": {
37
+ "file": "tables.md",
38
+ "purpose": "Table schema definitions",
39
+ "aliases": ["schema", "fields", "indexes"]
40
+ },
41
+ "apis": {
42
+ "file": "apis.md",
43
+ "purpose": "HTTP endpoint definitions",
44
+ "aliases": ["endpoints", "http", "rest", "query"]
45
+ },
46
+ "functions": {
47
+ "file": "functions.md",
48
+ "purpose": "Reusable function stacks",
49
+ "aliases": ["fn", "reusable", "stack"]
50
+ },
51
+ "triggers": {
52
+ "file": "triggers.md",
53
+ "purpose": "Event-driven handlers",
54
+ "aliases": ["events", "hooks", "handlers"]
55
+ },
56
+ "agents": {
57
+ "file": "agents.md",
58
+ "purpose": "AI agent configuration",
59
+ "aliases": ["ai", "llm", "chatbot"]
60
+ },
61
+ "tools": {
62
+ "file": "tools.md",
63
+ "purpose": "AI tools for agents",
64
+ "aliases": ["ai-tools", "agent-tools"]
65
+ },
66
+ "integrations": {
67
+ "file": "integrations.md",
68
+ "purpose": "External service integrations (index)",
69
+ "aliases": ["external", "services", "cloud"]
70
+ },
71
+ "integrations/cloud-storage": {
72
+ "file": "integrations/cloud-storage.md",
73
+ "purpose": "AWS S3, Azure Blob, GCP Storage",
74
+ "aliases": ["s3", "azure", "gcp", "files", "upload"]
75
+ },
76
+ "integrations/search": {
77
+ "file": "integrations/search.md",
78
+ "purpose": "Elasticsearch, Algolia",
79
+ "aliases": ["elasticsearch", "algolia", "full-text"]
80
+ },
81
+ "integrations/redis": {
82
+ "file": "integrations/redis.md",
83
+ "purpose": "Caching, rate limiting, queues",
84
+ "aliases": ["cache", "rate-limit", "queue"]
85
+ },
86
+ "integrations/external-apis": {
87
+ "file": "integrations/external-apis.md",
88
+ "purpose": "api.request patterns",
89
+ "aliases": ["http", "api", "request", "fetch"]
90
+ },
91
+ "integrations/utilities": {
92
+ "file": "integrations/utilities.md",
93
+ "purpose": "Email, Zip, Lambda",
94
+ "aliases": ["email", "zip", "lambda", "archive"]
95
+ },
96
+ "security": {
97
+ "file": "security.md",
98
+ "purpose": "Authentication, authorization, security patterns",
99
+ "aliases": ["auth", "authorization", "permissions"]
100
+ },
101
+ "performance": {
102
+ "file": "performance.md",
103
+ "purpose": "Optimization best practices",
104
+ "aliases": ["optimization", "speed", "caching"]
105
+ },
106
+ "mcp-servers": {
107
+ "file": "mcp-servers.md",
108
+ "purpose": "MCP server configuration",
109
+ "aliases": ["mcp", "model-context-protocol"]
110
+ },
111
+ "tasks": {
112
+ "file": "tasks.md",
113
+ "purpose": "Scheduled job definitions",
114
+ "aliases": ["scheduled", "jobs", "cron"]
115
+ },
116
+ "streaming": {
117
+ "file": "streaming.md",
118
+ "purpose": "Streaming data handling",
119
+ "aliases": ["stream", "large-files"]
120
+ },
121
+ "realtime": {
122
+ "file": "realtime.md",
123
+ "purpose": "Real-time channel configuration",
124
+ "aliases": ["websocket", "channels", "pubsub"]
125
+ },
126
+ "middleware": {
127
+ "file": "middleware.md",
128
+ "purpose": "Request interceptors",
129
+ "aliases": ["interceptors", "hooks"]
130
+ },
131
+ "unit-testing": {
132
+ "file": "unit-testing.md",
133
+ "purpose": "Unit tests, mocks, and assertions",
134
+ "aliases": ["tests", "unit-tests", "mocks", "assertions"]
135
+ },
136
+ "workflow-tests": {
137
+ "file": "workflow-tests.md",
138
+ "purpose": "End-to-end workflow tests",
139
+ "aliases": ["e2e", "workflow", "integration-tests"]
140
+ },
141
+ "debugging": {
142
+ "file": "debugging.md",
143
+ "purpose": "Logging and debugging",
144
+ "aliases": ["logs", "debug", "trace"]
145
+ }
146
+ },
147
+
148
+ "filters": {
149
+ "trim": { "file": "syntax.md", "category": "string" },
150
+ "ltrim": { "file": "syntax.md", "category": "string" },
151
+ "rtrim": { "file": "syntax.md", "category": "string" },
152
+ "to_lower": { "file": "syntax.md", "category": "string" },
153
+ "to_upper": { "file": "syntax.md", "category": "string" },
154
+ "capitalize": { "file": "syntax.md", "category": "string" },
155
+ "substr": { "file": "syntax.md", "category": "string" },
156
+ "split": { "file": "syntax.md", "category": "string" },
157
+ "replace": { "file": "syntax.md", "category": "string" },
158
+ "contains": { "file": "syntax.md", "category": "string" },
159
+ "strlen": { "file": "syntax.md", "category": "string" },
160
+ "first": { "file": "syntax.md", "category": "array" },
161
+ "last": { "file": "syntax.md", "category": "array" },
162
+ "count": { "file": "syntax.md", "category": "array" },
163
+ "map": { "file": "syntax.md", "category": "array" },
164
+ "filter": { "file": "syntax.md", "category": "array" },
165
+ "find": { "file": "syntax.md", "category": "array" },
166
+ "reduce": { "file": "syntax.md", "category": "array" },
167
+ "push": { "file": "syntax.md", "category": "array" },
168
+ "pop": { "file": "syntax.md", "category": "array" },
169
+ "join": { "file": "syntax.md", "category": "array" },
170
+ "sort": { "file": "syntax.md", "category": "array" },
171
+ "unique": { "file": "syntax.md", "category": "array" },
172
+ "get": { "file": "syntax.md", "category": "object" },
173
+ "set": { "file": "syntax.md", "category": "object" },
174
+ "has": { "file": "syntax.md", "category": "object" },
175
+ "keys": { "file": "syntax.md", "category": "object" },
176
+ "values": { "file": "syntax.md", "category": "object" },
177
+ "to_int": { "file": "syntax.md", "category": "type" },
178
+ "to_text": { "file": "syntax.md", "category": "type" },
179
+ "to_bool": { "file": "syntax.md", "category": "type" },
180
+ "to_decimal": { "file": "syntax.md", "category": "type" },
181
+ "json_encode": { "file": "syntax.md", "category": "type" },
182
+ "json_decode": { "file": "syntax.md", "category": "type" },
183
+ "round": { "file": "syntax.md", "category": "math" },
184
+ "abs": { "file": "syntax.md", "category": "math" },
185
+ "ceil": { "file": "syntax.md", "category": "math" },
186
+ "floor": { "file": "syntax.md", "category": "math" },
187
+ "add": { "file": "syntax.md", "category": "math" },
188
+ "subtract": { "file": "syntax.md", "category": "math" }
189
+ },
190
+
191
+ "constructs": {
192
+ "table": { "file": "tables.md", "triggers": "triggers.md" },
193
+ "function": { "file": "functions.md", "testing": "unit-testing.md" },
194
+ "query": { "file": "apis.md", "auth": "security.md" },
195
+ "api_group": { "file": "apis.md" },
196
+ "task": { "file": "tasks.md" },
197
+ "agent": { "file": "agents.md", "tools": "tools.md" },
198
+ "tool": { "file": "tools.md", "mcp": "mcp-servers.md" },
199
+ "mcp_server": { "file": "mcp-servers.md", "triggers": "triggers.md" },
200
+ "table_trigger": { "file": "triggers.md", "section": "table-trigger" },
201
+ "realtime_trigger": { "file": "triggers.md", "section": "realtime-trigger" },
202
+ "workspace_trigger": { "file": "triggers.md", "section": "workspace-trigger" },
203
+ "agent_trigger": { "file": "triggers.md", "section": "agent-trigger" },
204
+ "mcp_server_trigger": { "file": "triggers.md", "section": "mcp-server-trigger" },
205
+ "addon": { "file": "addons.md" },
206
+ "middleware": { "file": "middleware.md" },
207
+ "realtime_channel": { "file": "realtime.md" }
208
+ },
209
+
210
+ "operations": {
211
+ "db.query": { "file": "database.md" },
212
+ "db.get": { "file": "database.md" },
213
+ "db.has": { "file": "database.md" },
214
+ "db.add": { "file": "database.md" },
215
+ "db.edit": { "file": "database.md" },
216
+ "db.patch": { "file": "database.md" },
217
+ "db.del": { "file": "database.md" },
218
+ "db.truncate": { "file": "database.md" },
219
+ "api.request": { "file": "integrations/external-apis.md" },
220
+ "function.run": { "file": "functions.md" },
221
+ "redis.get": { "file": "integrations/redis.md" },
222
+ "redis.set": { "file": "integrations/redis.md" },
223
+ "storage.s3_put": { "file": "integrations/cloud-storage.md" },
224
+ "storage.s3_get": { "file": "integrations/cloud-storage.md" }
225
+ },
226
+
227
+ "tasks": {
228
+ "authentication": ["security.md", "apis.md"],
229
+ "authorization": ["security.md"],
230
+ "rate_limiting": ["security.md", "integrations/redis.md"],
231
+ "error_handling": ["syntax.md", "quickstart.md"],
232
+ "pagination": ["database.md", "apis.md"],
233
+ "file_upload": ["integrations/cloud-storage.md", "streaming.md"],
234
+ "caching": ["performance.md", "integrations/redis.md"],
235
+ "search": ["integrations/search.md"],
236
+ "email": ["integrations/utilities.md"],
237
+ "scheduled_jobs": ["tasks.md"],
238
+ "realtime": ["realtime.md", "triggers.md"],
239
+ "ai_agents": ["agents.md", "tools.md", "mcp-servers.md"]
240
+ }
241
+ }
@@ -286,3 +286,13 @@ The tool will:
286
286
  2. **Centralize API calls** - Single `api.js` file
287
287
  3. **Store tokens securely** - localStorage for web, secure storage for mobile
288
288
  4. **Test incrementally** - Migrate one feature at a time
289
+
290
+ ---
291
+
292
+ ## Related Topics
293
+
294
+ | Topic | Description |
295
+ |-------|-------------|
296
+ | `apis` | Backend API endpoints |
297
+ | `workspace` | Workspace configuration |
298
+ | `security` | CORS and authentication |
@@ -6,6 +6,10 @@ applyTo: "function/**/*.xs"
6
6
 
7
7
  Reusable logic blocks in XanoScript.
8
8
 
9
+ > **TL;DR:** Define with `function "name" { input { } stack { } response = $result }`. Call with `function.run "name" { input = { } } as $result`. Empty input blocks need braces on separate lines.
10
+
11
+ ---
12
+
9
13
  ## Quick Reference
10
14
 
11
15
  ```xs
@@ -0,0 +1,142 @@
1
+ ---
2
+ applyTo: "function/**/*.xs, api/**/*.xs, task/**/*.xs"
3
+ ---
4
+
5
+ # Cloud Storage Integrations
6
+
7
+ > **TL;DR:** `cloud.aws.s3.*` for AWS, `cloud.azure.storage.*` for Azure, `cloud.google.storage.*` for GCP. All support upload, read, delete, and signed URLs.
8
+
9
+ ## Quick Reference
10
+
11
+ | Provider | Prefix | Operations |
12
+ |----------|--------|------------|
13
+ | AWS S3 | `cloud.aws.s3.*` | upload_file, read_file, sign_url, list_directory, delete_file |
14
+ | Azure Blob | `cloud.azure.storage.*` | upload_file, read_file, sign_url |
15
+ | Google Cloud | `cloud.google.storage.*` | upload_file, read_file, sign_url |
16
+
17
+ ---
18
+
19
+ ## AWS S3
20
+
21
+ ### Upload File
22
+ ```xs
23
+ cloud.aws.s3.upload_file {
24
+ bucket = "my-bucket"
25
+ region = "us-east-1"
26
+ key = $env.AWS_ACCESS_KEY
27
+ secret = $env.AWS_SECRET_KEY
28
+ file_key = "uploads/" ~ $input.filename
29
+ file = $input.file
30
+ } as $result
31
+ ```
32
+
33
+ ### Read File
34
+ ```xs
35
+ cloud.aws.s3.read_file {
36
+ bucket = "my-bucket"
37
+ region = "us-east-1"
38
+ key = $env.AWS_ACCESS_KEY
39
+ secret = $env.AWS_SECRET_KEY
40
+ file_key = "data/config.json"
41
+ } as $file
42
+ ```
43
+
44
+ ### Sign URL
45
+ ```xs
46
+ cloud.aws.s3.sign_url {
47
+ bucket = "my-bucket"
48
+ region = "us-east-1"
49
+ key = $env.AWS_ACCESS_KEY
50
+ secret = $env.AWS_SECRET_KEY
51
+ file_key = "private/document.pdf"
52
+ ttl = 300
53
+ } as $signed_url
54
+ ```
55
+
56
+ ### List Directory
57
+ ```xs
58
+ cloud.aws.s3.list_directory {
59
+ bucket = "my-bucket"
60
+ region = "us-east-1"
61
+ key = $env.AWS_ACCESS_KEY
62
+ secret = $env.AWS_SECRET_KEY
63
+ prefix = "uploads/"
64
+ } as $files
65
+ ```
66
+
67
+ ### Delete File
68
+ ```xs
69
+ cloud.aws.s3.delete_file {
70
+ bucket = "my-bucket"
71
+ region = "us-east-1"
72
+ key = $env.AWS_ACCESS_KEY
73
+ secret = $env.AWS_SECRET_KEY
74
+ file_key = "temp/old-file.txt"
75
+ }
76
+ ```
77
+
78
+ ---
79
+
80
+ ## Azure Blob Storage
81
+
82
+ ```xs
83
+ cloud.azure.storage.upload_file {
84
+ account_name = $env.AZURE_ACCOUNT
85
+ account_key = $env.AZURE_KEY
86
+ container_name = "files"
87
+ filePath = "uploads/doc.pdf"
88
+ file = $input.file
89
+ }
90
+
91
+ cloud.azure.storage.read_file {
92
+ account_name = $env.AZURE_ACCOUNT
93
+ account_key = $env.AZURE_KEY
94
+ container_name = "files"
95
+ filePath = "data/config.json"
96
+ } as $file
97
+
98
+ cloud.azure.storage.sign_url {
99
+ account_name = $env.AZURE_ACCOUNT
100
+ account_key = $env.AZURE_KEY
101
+ container_name = "private"
102
+ path = "document.pdf"
103
+ ttl = 300
104
+ } as $url
105
+ ```
106
+
107
+ ---
108
+
109
+ ## Google Cloud Storage
110
+
111
+ ```xs
112
+ cloud.google.storage.upload_file {
113
+ service_account = $env.GCP_SERVICE_ACCOUNT
114
+ bucket = "my-bucket"
115
+ filePath = "uploads/file.pdf"
116
+ file = $input.file
117
+ }
118
+
119
+ cloud.google.storage.read_file {
120
+ service_account = $env.GCP_SERVICE_ACCOUNT
121
+ bucket = "my-bucket"
122
+ filePath = "data/config.json"
123
+ } as $file
124
+
125
+ cloud.google.storage.sign_url {
126
+ service_account = $env.GCP_SERVICE_ACCOUNT
127
+ bucket = "my-bucket"
128
+ filePath = "private/doc.pdf"
129
+ method = "GET"
130
+ ttl = 300
131
+ } as $url
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Related Topics
137
+
138
+ | Topic | Description |
139
+ |-------|-------------|
140
+ | `streaming` | Streaming large files |
141
+ | `integrations` | All integrations index |
142
+ | `integrations/utilities` | Local storage operations |
@@ -0,0 +1,201 @@
1
+ ---
2
+ applyTo: "function/**/*.xs, api/**/*.xs, task/**/*.xs"
3
+ ---
4
+
5
+ # External APIs
6
+
7
+ > **TL;DR:** Use `api.request` for HTTP requests to external APIs. The `params` parameter is for the **request body** (not query params). Response in `$result.response.result`.
8
+
9
+ ## Quick Reference
10
+
11
+ ```xs
12
+ api.request {
13
+ url = "https://api.example.com/endpoint"
14
+ method = "POST" // GET, POST, PUT, PATCH, DELETE
15
+ params = $payload // Request body for POST/PUT/PATCH
16
+ headers = ["Content-Type: application/json", "Authorization: Bearer " ~ $env.API_KEY]
17
+ timeout = 30 // Timeout in seconds
18
+ } as $api_result
19
+
20
+ // Access response
21
+ $api_result.response.status // HTTP status code (200, 404, etc.)
22
+ $api_result.response.result // Response body (auto-parsed JSON)
23
+ $api_result.response.headers // Response headers array
24
+ ```
25
+
26
+ > **Important:** The `params` parameter is used for the **request body** (POST/PUT/PATCH), not query parameters. This naming is counterintuitive but consistent across XanoScript.
27
+
28
+ > **Note:** The `headers` parameter expects an array of text strings, where each string contains the header name and value separated by a colon (e.g., `["Content-Type: application/json", "X-Custom-Header: value"]`).
29
+
30
+ ---
31
+
32
+ ## GET Request
33
+
34
+ ```xs
35
+ api.request {
36
+ url = "https://api.example.com/users?page=1&limit=10"
37
+ method = "GET"
38
+ headers = ["Authorization: Bearer " ~ $env.API_KEY]
39
+ } as $api_result
40
+
41
+ var $users { value = $api_result.response.result }
42
+ ```
43
+
44
+ ---
45
+
46
+ ## POST Request with JSON Body
47
+
48
+ ```xs
49
+ var $payload {
50
+ value = {
51
+ name: $input.name,
52
+ email: $input.email
53
+ }
54
+ }
55
+
56
+ api.request {
57
+ url = "https://api.example.com/users"
58
+ method = "POST"
59
+ params = $payload
60
+ headers = ["Content-Type: application/json", "Authorization: Bearer " ~ $env.API_KEY]
61
+ } as $api_result
62
+
63
+ // Check for success
64
+ precondition ($api_result.response.status == 201) {
65
+ error_type = "standard"
66
+ error = "Failed to create user: " ~ ($api_result.response.result|json_encode)
67
+ }
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Error Handling Pattern
73
+
74
+ ```xs
75
+ api.request {
76
+ url = "https://api.example.com/data"
77
+ method = "GET"
78
+ timeout = 30
79
+ } as $api_result
80
+
81
+ conditional {
82
+ if ($api_result.response.status >= 200 && $api_result.response.status < 300) {
83
+ var $data { value = $api_result.response.result }
84
+ }
85
+ elseif ($api_result.response.status == 404) {
86
+ throw { name = "NotFound", value = "Resource not found" }
87
+ }
88
+ else {
89
+ throw {
90
+ name = "APIError",
91
+ value = "API returned status " ~ ($api_result.response.status|to_text)
92
+ }
93
+ }
94
+ }
95
+ ```
96
+
97
+ ---
98
+
99
+ ## Response Structure
100
+
101
+ The `api.request` statement returns an object with both request and response details:
102
+
103
+ ```json
104
+ {
105
+ "request": {
106
+ "url": "", // The URL that was requested
107
+ "method": "", // HTTP method used (GET, POST, etc.)
108
+ "headers": [], // Array of request headers sent
109
+ "params": [] // Parameters sent with the request
110
+ },
111
+ "response": {
112
+ "headers": [], // Array of response headers received
113
+ "result": "", // Response body (can be any format: JSON, string, null, boolean, etc.)
114
+ "status": 200 // HTTP status code
115
+ }
116
+ }
117
+ ```
118
+
119
+ ---
120
+
121
+ ## Accessing Response Data
122
+
123
+ ```xs
124
+ api.request {
125
+ url = "https://api.example.com/users"
126
+ method = "GET"
127
+ } as $api_result
128
+
129
+ // Access the response body
130
+ var $data { value = $api_result.response.result }
131
+
132
+ // Check status code
133
+ precondition ($api_result.response.status == 200) {
134
+ error_type = "standard"
135
+ error = "API request failed"
136
+ }
137
+
138
+ // Access a specific header
139
+ var $content_type { value = $api_result.response.headers|first }
140
+ ```
141
+
142
+ ---
143
+
144
+ ## Common Patterns
145
+
146
+ ### Retry Logic
147
+
148
+ ```xs
149
+ var $retries { value = 0 }
150
+ var $success { value = false }
151
+
152
+ while ($retries < 3 && $success == false) {
153
+ try_catch {
154
+ try {
155
+ api.request {
156
+ url = "https://api.example.com/data"
157
+ method = "GET"
158
+ timeout = 10
159
+ } as $api_result
160
+
161
+ conditional {
162
+ if ($api_result.response.status == 200) {
163
+ var.update $success { value = true }
164
+ }
165
+ }
166
+ }
167
+ catch {
168
+ var.update $retries { value = $retries + 1 }
169
+ util.sleep { value = 2 }
170
+ }
171
+ }
172
+ }
173
+ ```
174
+
175
+ ### Webhook Callback
176
+
177
+ ```xs
178
+ api.request {
179
+ url = $env.WEBHOOK_URL
180
+ method = "POST"
181
+ params = {
182
+ event: "order.created",
183
+ data: $order,
184
+ timestamp: now
185
+ }
186
+ headers = [
187
+ "Content-Type: application/json",
188
+ "X-Webhook-Signature: " ~ $signature
189
+ ]
190
+ }
191
+ ```
192
+
193
+ ---
194
+
195
+ ## Related Topics
196
+
197
+ | Topic | Description |
198
+ |-------|-------------|
199
+ | `syntax` | Error handling with try_catch |
200
+ | `integrations/utilities` | Lambda invocation |
201
+ | `integrations` | All integrations index |