atris 2.5.1 → 2.5.3
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.
- package/atris/skills/create-app/SKILL.md +40 -13
- package/atris/skills/drive/SKILL.md +335 -20
- package/atris/skills/ramp/SKILL.md +295 -0
- package/package.json +1 -1
|
@@ -54,20 +54,9 @@ Auth header: `Authorization: Bearer $TOKEN`
|
|
|
54
54
|
|
|
55
55
|
Adapt the flow based on what the user described. Skip steps that don't apply.
|
|
56
56
|
|
|
57
|
-
### Step 0: Clarify Intent
|
|
58
|
-
|
|
59
|
-
Before building anything, ask the user:
|
|
60
|
-
|
|
61
|
-
1. **Personal or business?** — First check if the user has any businesses: `GET https://api.atris.ai/api/business` with their token. If empty, it's personal — don't ask, just proceed. If they have businesses, ask: "Is this just for you, or for [business name]?"
|
|
62
|
-
2. **How does data get in?** — Schedule (daily pull), webhook (data pushed in), manual (you trigger it), email, or chat?
|
|
63
|
-
3. **How should output reach you?** — Email, feed post, API (for a custom UI), or just stored for querying?
|
|
64
|
-
4. **Any API keys needed?** — Does this connect to an external service (Mixpanel, GitHub, Stripe, etc)?
|
|
65
|
-
|
|
66
|
-
Keep it conversational. Don't ask all 4 at once if the answer is obvious from context. A mood tracker is clearly personal, manual input, no API keys. A Mixpanel analytics app clearly needs an API key and a daily schedule.
|
|
67
|
-
|
|
68
57
|
### Step 1: Create the App
|
|
69
58
|
|
|
70
|
-
Ask the user for a name
|
|
59
|
+
Ask the user for a name. Generate a slug (lowercase, hyphens, no spaces).
|
|
71
60
|
|
|
72
61
|
```bash
|
|
73
62
|
curl -s -X POST "https://api.atris.ai/api/apps" \
|
|
@@ -96,7 +85,43 @@ Save the returned `id` as `APP_ID` and `share_token` as `SLUG`.
|
|
|
96
85
|
|
|
97
86
|
Only if the workflow needs external API access (Mixpanel, GitHub, Stripe, etc).
|
|
98
87
|
|
|
99
|
-
Ask the user for each key.
|
|
88
|
+
Ask the user for each key. **Default to local storage** (keys stay on their machine).
|
|
89
|
+
|
|
90
|
+
**Option A: Local storage (default, recommended)**
|
|
91
|
+
|
|
92
|
+
Keys are saved to `~/.atris/secrets/{SLUG}/` on the user's machine. They never leave the machine when using the CLI agent. If using the AI Computer, they're transmitted over TLS but never persisted on Atris infrastructure.
|
|
93
|
+
|
|
94
|
+
**macOS/Linux:**
|
|
95
|
+
```bash
|
|
96
|
+
mkdir -p ~/.atris/secrets/SLUG
|
|
97
|
+
read -s -p "Enter KEY_NAME: " secret_val
|
|
98
|
+
printf '%s' "$secret_val" > ~/.atris/secrets/SLUG/KEY_NAME
|
|
99
|
+
chmod 600 ~/.atris/secrets/SLUG/KEY_NAME
|
|
100
|
+
unset secret_val
|
|
101
|
+
echo "Saved locally."
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Windows (PowerShell):**
|
|
105
|
+
```powershell
|
|
106
|
+
$dir = "$env:USERPROFILE\.atris\secrets\SLUG"
|
|
107
|
+
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
108
|
+
$val = Read-Host -Prompt "Enter KEY_NAME" -AsSecureString
|
|
109
|
+
$plain = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($val))
|
|
110
|
+
Set-Content -Path "$dir\KEY_NAME" -Value $plain -NoNewline
|
|
111
|
+
icacls "$dir\KEY_NAME" /inheritance:r /grant:r "${env:USERNAME}:(R,W)" | Out-Null
|
|
112
|
+
Remove-Variable plain, val
|
|
113
|
+
Write-Host "Saved locally."
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Verify (key names only, never values):
|
|
117
|
+
```bash
|
|
118
|
+
ls ~/.atris/secrets/SLUG/ # macOS/Linux
|
|
119
|
+
dir $env:USERPROFILE\.atris\secrets\SLUG # Windows
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Option B: Cloud storage (cross-device access)**
|
|
123
|
+
|
|
124
|
+
If the user needs secrets accessible from any device or the web UI, store in the encrypted cloud vault:
|
|
100
125
|
|
|
101
126
|
```bash
|
|
102
127
|
curl -s -X PUT "https://api.atris.ai/api/apps/SLUG/secrets/KEY_NAME" \
|
|
@@ -107,6 +132,8 @@ curl -s -X PUT "https://api.atris.ai/api/apps/SLUG/secrets/KEY_NAME" \
|
|
|
107
132
|
|
|
108
133
|
Never log or display the secret value after storing it.
|
|
109
134
|
|
|
135
|
+
**Always ask the user which storage tier they prefer before storing keys.** Explain: "Local means keys stay on your machine. Cloud means they're encrypted and available from any device."
|
|
136
|
+
|
|
110
137
|
**Skip this step** if the app doesn't need external API keys (chat apps, simple forms).
|
|
111
138
|
|
|
112
139
|
### Step 3: Create the Agent + Skill (if needed)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: drive
|
|
3
|
-
description: Google Drive integration via AtrisOS API.
|
|
4
|
-
version:
|
|
3
|
+
description: Google Drive integration via AtrisOS API. Full file management (upload, copy, share, move, delete), Google Docs (create, edit, format, templates), Google Sheets (read, write, format, charts). Use when user asks about Drive, files, docs, sheets, or spreadsheets.
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
tags:
|
|
6
6
|
- drive
|
|
7
7
|
- backend
|
|
@@ -222,12 +222,209 @@ curl -s -X PUT "https://api.atris.ai/api/integrations/google-drive/files/{file_i
|
|
|
222
222
|
}'
|
|
223
223
|
```
|
|
224
224
|
|
|
225
|
+
### Delete / Trash File
|
|
226
|
+
```bash
|
|
227
|
+
# Move to trash (recoverable)
|
|
228
|
+
curl -s -X DELETE "https://api.atris.ai/api/integrations/google-drive/files/{file_id}?trash=true" \
|
|
229
|
+
-H "Authorization: Bearer $TOKEN"
|
|
230
|
+
|
|
231
|
+
# Permanently delete (irreversible)
|
|
232
|
+
curl -s -X DELETE "https://api.atris.ai/api/integrations/google-drive/files/{file_id}" \
|
|
233
|
+
-H "Authorization: Bearer $TOKEN"
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Copy File
|
|
237
|
+
```bash
|
|
238
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/copy" \
|
|
239
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
240
|
+
-H "Content-Type: application/json" \
|
|
241
|
+
-d '{"name": "Copy of Document", "folder_id": "OPTIONAL_FOLDER_ID"}'
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Works with Docs, Sheets, Slides — creates a full copy.
|
|
245
|
+
|
|
246
|
+
### Share File
|
|
247
|
+
```bash
|
|
248
|
+
# Share with a specific user
|
|
249
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/share" \
|
|
250
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
251
|
+
-H "Content-Type: application/json" \
|
|
252
|
+
-d '{"email": "user@example.com", "role": "writer", "notify": true}'
|
|
253
|
+
|
|
254
|
+
# Share with anyone who has the link
|
|
255
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/share" \
|
|
256
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
257
|
+
-H "Content-Type: application/json" \
|
|
258
|
+
-d '{"anyone": true, "role": "reader"}'
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
Roles: `reader`, `writer`, `commenter`
|
|
262
|
+
|
|
263
|
+
### Create Folder
|
|
264
|
+
```bash
|
|
265
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/folders" \
|
|
266
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
267
|
+
-H "Content-Type: application/json" \
|
|
268
|
+
-d '{"name": "Project Files", "parent_id": "OPTIONAL_PARENT_FOLDER_ID"}'
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Move File
|
|
272
|
+
```bash
|
|
273
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/move" \
|
|
274
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
275
|
+
-H "Content-Type: application/json" \
|
|
276
|
+
-d '{"new_parent_id": "TARGET_FOLDER_ID"}'
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
### Pagination
|
|
280
|
+
|
|
281
|
+
List and search endpoints return `next_page_token` when there are more results. Pass it to get the next page:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
curl -s "https://api.atris.ai/api/integrations/google-drive/files?page_size=20&page_token=NEXT_PAGE_TOKEN" \
|
|
285
|
+
-H "Authorization: Bearer $TOKEN"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Works on: `/files`, `/search`, `/shared-drives`
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## Google Docs
|
|
293
|
+
|
|
294
|
+
Native Google Docs creation and editing. Uses the same Drive OAuth connection.
|
|
295
|
+
|
|
296
|
+
### List Google Docs
|
|
297
|
+
```bash
|
|
298
|
+
curl -s "https://api.atris.ai/api/integrations/google-docs/documents?page_size=20" \
|
|
299
|
+
-H "Authorization: Bearer $TOKEN"
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Create a New Google Doc
|
|
303
|
+
```bash
|
|
304
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents" \
|
|
305
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
306
|
+
-H "Content-Type: application/json" \
|
|
307
|
+
-d '{"title": "Q1 2026 Report"}'
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
Returns `documentId` and `url` (direct link to edit in browser).
|
|
311
|
+
|
|
312
|
+
### Read a Google Doc
|
|
313
|
+
```bash
|
|
314
|
+
curl -s "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}" \
|
|
315
|
+
-H "Authorization: Bearer $TOKEN"
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Returns full document structure (body, paragraphs, text runs, styles).
|
|
319
|
+
|
|
320
|
+
### Insert Text into a Doc
|
|
321
|
+
```bash
|
|
322
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/batch-update" \
|
|
323
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
324
|
+
-H "Content-Type: application/json" \
|
|
325
|
+
-d '{
|
|
326
|
+
"requests": [
|
|
327
|
+
{
|
|
328
|
+
"insertText": {
|
|
329
|
+
"location": {"index": 1},
|
|
330
|
+
"text": "Hello, this is the first paragraph.\n\nSecond paragraph here.\n"
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
]
|
|
334
|
+
}'
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Text is inserted at a character index.** Index 1 = start of document body. Newlines create paragraphs.
|
|
338
|
+
|
|
339
|
+
### Replace Placeholders in a Doc Template
|
|
340
|
+
```bash
|
|
341
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/batch-update" \
|
|
342
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
343
|
+
-H "Content-Type: application/json" \
|
|
344
|
+
-d '{
|
|
345
|
+
"requests": [
|
|
346
|
+
{
|
|
347
|
+
"replaceAllText": {
|
|
348
|
+
"containsText": {"text": "{{client_name}}", "matchCase": true},
|
|
349
|
+
"replaceText": "Acme Corp"
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
"replaceAllText": {
|
|
354
|
+
"containsText": {"text": "{{date}}", "matchCase": true},
|
|
355
|
+
"replaceText": "March 5, 2026"
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
]
|
|
359
|
+
}'
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### Format Text (Bold, Italic, Font Size, Color)
|
|
363
|
+
```bash
|
|
364
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/batch-update" \
|
|
365
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
366
|
+
-H "Content-Type: application/json" \
|
|
367
|
+
-d '{
|
|
368
|
+
"requests": [
|
|
369
|
+
{
|
|
370
|
+
"updateTextStyle": {
|
|
371
|
+
"range": {"startIndex": 1, "endIndex": 20},
|
|
372
|
+
"textStyle": {"bold": true, "fontSize": {"magnitude": 18, "unit": "PT"}},
|
|
373
|
+
"fields": "bold,fontSize"
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
]
|
|
377
|
+
}'
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
### Insert a Table
|
|
381
|
+
```bash
|
|
382
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/batch-update" \
|
|
383
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
384
|
+
-H "Content-Type: application/json" \
|
|
385
|
+
-d '{
|
|
386
|
+
"requests": [
|
|
387
|
+
{
|
|
388
|
+
"insertTable": {
|
|
389
|
+
"rows": 3,
|
|
390
|
+
"columns": 2,
|
|
391
|
+
"location": {"index": 1}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
]
|
|
395
|
+
}'
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
### Export Doc as PDF
|
|
399
|
+
```bash
|
|
400
|
+
curl -s "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/export" \
|
|
401
|
+
-H "Authorization: Bearer $TOKEN"
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
Returns base64-encoded PDF.
|
|
405
|
+
|
|
406
|
+
### Export Doc as Plain Text
|
|
407
|
+
```bash
|
|
408
|
+
curl -s "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/text" \
|
|
409
|
+
-H "Authorization: Bearer $TOKEN"
|
|
410
|
+
```
|
|
411
|
+
|
|
225
412
|
---
|
|
226
413
|
|
|
227
414
|
## Google Sheets
|
|
228
415
|
|
|
229
416
|
Full read/write access to Google Sheets.
|
|
230
417
|
|
|
418
|
+
### Create a Spreadsheet
|
|
419
|
+
```bash
|
|
420
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets" \
|
|
421
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
422
|
+
-H "Content-Type: application/json" \
|
|
423
|
+
-d '{"title": "Q1 Revenue Tracker"}'
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
Returns `spreadsheetId` and `url` (direct link to edit in browser).
|
|
427
|
+
|
|
231
428
|
### Get Spreadsheet Info
|
|
232
429
|
```bash
|
|
233
430
|
curl -s "https://api.atris.ai/api/integrations/google-drive/sheets/{spreadsheet_id}" \
|
|
@@ -276,10 +473,65 @@ curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets/{spre
|
|
|
276
473
|
}'
|
|
277
474
|
```
|
|
278
475
|
|
|
476
|
+
### Format Cells (batchUpdate)
|
|
477
|
+
|
|
478
|
+
Apply formatting, merges, conditional formatting, charts, and other structural changes.
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets/{spreadsheet_id}/batchUpdate" \
|
|
482
|
+
-H "Authorization: Bearer $TOKEN" \
|
|
483
|
+
-H "Content-Type: application/json" \
|
|
484
|
+
-d '{
|
|
485
|
+
"requests": [
|
|
486
|
+
{
|
|
487
|
+
"repeatCell": {
|
|
488
|
+
"range": {"sheetId": 0, "startRowIndex": 0, "endRowIndex": 1},
|
|
489
|
+
"cell": {
|
|
490
|
+
"userEnteredFormat": {
|
|
491
|
+
"textFormat": {"bold": true},
|
|
492
|
+
"backgroundColor": {"red": 0.9, "green": 0.9, "blue": 0.9}
|
|
493
|
+
}
|
|
494
|
+
},
|
|
495
|
+
"fields": "userEnteredFormat(textFormat,backgroundColor)"
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
]
|
|
499
|
+
}'
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
**Common request types:**
|
|
503
|
+
- `repeatCell` — format a range (bold, colors, font size, alignment)
|
|
504
|
+
- `mergeCells` — merge a range into one cell
|
|
505
|
+
- `updateBorders` — add borders to cells
|
|
506
|
+
- `autoResizeDimensions` — auto-fit column widths
|
|
507
|
+
- `addConditionalFormatRule` — highlight cells based on rules
|
|
508
|
+
- `addChart` — embed a chart
|
|
509
|
+
- `addSheet` / `deleteSheet` — manage sheets/tabs
|
|
510
|
+
- `sortRange` — sort rows by a column
|
|
511
|
+
|
|
512
|
+
**Range format:** `{"sheetId": 0, "startRowIndex": 0, "endRowIndex": 1, "startColumnIndex": 0, "endColumnIndex": 3}` — sheetId 0 = first tab, indices are 0-based.
|
|
513
|
+
|
|
514
|
+
**Color format:** RGB floats 0-1, e.g. `{"red": 0.2, "green": 0.6, "blue": 1.0}`
|
|
515
|
+
|
|
516
|
+
You can send multiple requests in one call — they execute in order.
|
|
517
|
+
|
|
279
518
|
---
|
|
280
519
|
|
|
281
520
|
## Workflows
|
|
282
521
|
|
|
522
|
+
### "Create a Google Doc with content"
|
|
523
|
+
1. Run bootstrap
|
|
524
|
+
2. Create doc: `POST /google-docs/documents` with `{"title": "..."}`
|
|
525
|
+
3. Insert text: `POST /google-docs/documents/{id}/batch-update` with `insertText` requests
|
|
526
|
+
4. Return the edit URL to user
|
|
527
|
+
|
|
528
|
+
### "Fill a doc template"
|
|
529
|
+
1. Run bootstrap
|
|
530
|
+
2. Copy template: `POST /files/{template_id}/copy` with `{"name": "Client Proposal"}`
|
|
531
|
+
3. Replace placeholders: `POST /google-docs/documents/{new_id}/batch-update` with `replaceAllText` requests
|
|
532
|
+
4. Share if needed: `POST /files/{id}/share`
|
|
533
|
+
5. Return URL
|
|
534
|
+
|
|
283
535
|
### "Find a file in my Drive"
|
|
284
536
|
1. Run bootstrap
|
|
285
537
|
2. Search: `GET /google-drive/search?q=QUERY`
|
|
@@ -316,25 +568,44 @@ curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets/{spre
|
|
|
316
568
|
2. Search: `GET /google-drive/search?q=QUERY` (automatically searches My Drive + all shared drives)
|
|
317
569
|
3. Display results
|
|
318
570
|
|
|
319
|
-
### "
|
|
571
|
+
### "Format a spreadsheet"
|
|
572
|
+
1. Run bootstrap
|
|
573
|
+
2. Find the sheet, get its `spreadsheetId`
|
|
574
|
+
3. Build requests array — bold headers, colors, borders, auto-resize, etc.
|
|
575
|
+
4. **Show user what formatting will be applied, get approval**
|
|
576
|
+
5. Apply: `POST /google-drive/sheets/{id}/batchUpdate` with `{"requests": [...]}`
|
|
577
|
+
|
|
578
|
+
### "Create a spreadsheet with data"
|
|
579
|
+
1. Run bootstrap
|
|
580
|
+
2. Create: `POST /google-drive/sheets` with `{"title": "..."}`
|
|
581
|
+
3. Write headers + data: `PUT /google-drive/sheets/{id}/values` with range + values
|
|
582
|
+
4. Format headers: `POST /google-drive/sheets/{id}/batchUpdate` (bold, background color)
|
|
583
|
+
5. Return the URL
|
|
584
|
+
|
|
585
|
+
### "Share a file"
|
|
586
|
+
1. Run bootstrap
|
|
587
|
+
2. Find the file
|
|
588
|
+
3. **Ask user**: share with specific email or anyone with link?
|
|
589
|
+
4. Share: `POST /google-drive/files/{id}/share`
|
|
590
|
+
|
|
591
|
+
### "Organize files into folders"
|
|
592
|
+
1. Run bootstrap
|
|
593
|
+
2. Create folder: `POST /google-drive/folders` with `{"name": "..."}`
|
|
594
|
+
3. Move files: `POST /google-drive/files/{id}/move` with `{"new_parent_id": "FOLDER_ID"}`
|
|
595
|
+
|
|
596
|
+
### "Copy a template"
|
|
597
|
+
1. Run bootstrap
|
|
598
|
+
2. Find the template file
|
|
599
|
+
3. Copy: `POST /google-drive/files/{id}/copy` with `{"name": "New Name"}`
|
|
600
|
+
4. If it's a Doc, replace placeholders via `/google-docs/documents/{new_id}/batch-update`
|
|
601
|
+
5. Share if needed
|
|
602
|
+
|
|
603
|
+
### "Delete files"
|
|
320
604
|
1. Run bootstrap
|
|
321
|
-
2.
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
-H "Content-Type: application/json" \
|
|
326
|
-
-d '{
|
|
327
|
-
"name": "My Document",
|
|
328
|
-
"content": "Document content here",
|
|
329
|
-
"mime_type": "application/vnd.google-apps.document"
|
|
330
|
-
}'
|
|
331
|
-
```
|
|
332
|
-
3. Returns file ID — the doc is now editable in Google Docs
|
|
333
|
-
|
|
334
|
-
**Native Google mime types for creation:**
|
|
335
|
-
- `application/vnd.google-apps.document` — Google Doc
|
|
336
|
-
- `application/vnd.google-apps.spreadsheet` — Google Sheet (content as CSV)
|
|
337
|
-
- `application/vnd.google-apps.presentation` — Google Slides
|
|
605
|
+
2. Find the files
|
|
606
|
+
3. **Confirm with user** — show file names
|
|
607
|
+
4. Trash (recoverable): `DELETE /google-drive/files/{id}?trash=true`
|
|
608
|
+
5. Or permanent delete: `DELETE /google-drive/files/{id}`
|
|
338
609
|
|
|
339
610
|
### "Upload a file to Drive"
|
|
340
611
|
1. Run bootstrap
|
|
@@ -412,8 +683,52 @@ curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files" \
|
|
|
412
683
|
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
413
684
|
-d '{"name":"notes.txt","content":"Hello world","mime_type":"text/plain"}'
|
|
414
685
|
|
|
686
|
+
# Create a folder
|
|
687
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/folders" \
|
|
688
|
+
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
689
|
+
-d '{"name":"Project Files"}'
|
|
690
|
+
|
|
691
|
+
# Copy a file
|
|
692
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/copy" \
|
|
693
|
+
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
694
|
+
-d '{"name":"Copy of Doc"}'
|
|
695
|
+
|
|
696
|
+
# Share with email
|
|
697
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/share" \
|
|
698
|
+
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
699
|
+
-d '{"email":"user@example.com","role":"writer"}'
|
|
700
|
+
|
|
701
|
+
# Move file to folder
|
|
702
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/move" \
|
|
703
|
+
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
704
|
+
-d '{"new_parent_id":"FOLDER_ID"}'
|
|
705
|
+
|
|
706
|
+
# Trash a file
|
|
707
|
+
curl -s -X DELETE "https://api.atris.ai/api/integrations/google-drive/files/{file_id}?trash=true" \
|
|
708
|
+
-H "Authorization: Bearer $TOKEN"
|
|
709
|
+
|
|
710
|
+
# Create a spreadsheet
|
|
711
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets" \
|
|
712
|
+
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
713
|
+
-d '{"title":"New Sheet"}'
|
|
714
|
+
|
|
715
|
+
# Format cells (bold header row)
|
|
716
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets/{id}/batchUpdate" \
|
|
717
|
+
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
718
|
+
-d '{"requests":[{"repeatCell":{"range":{"sheetId":0,"startRowIndex":0,"endRowIndex":1},"cell":{"userEnteredFormat":{"textFormat":{"bold":true}}},"fields":"userEnteredFormat.textFormat.bold"}}]}'
|
|
719
|
+
|
|
415
720
|
# Update an existing file
|
|
416
721
|
curl -s -X PUT "https://api.atris.ai/api/integrations/google-drive/files/{file_id}" \
|
|
417
722
|
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
418
723
|
-d '{"content":"Updated content","mime_type":"text/plain"}'
|
|
724
|
+
|
|
725
|
+
# Create a Google Doc
|
|
726
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents" \
|
|
727
|
+
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
728
|
+
-d '{"title":"New Doc"}'
|
|
729
|
+
|
|
730
|
+
# Insert text into a Doc
|
|
731
|
+
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents/DOC_ID/batch-update" \
|
|
732
|
+
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
|
733
|
+
-d '{"requests":[{"insertText":{"location":{"index":1},"text":"Hello world\n"}}]}'
|
|
419
734
|
```
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ramp
|
|
3
|
+
description: Ramp corporate card and spend management. Use when user asks about expenses, transactions, cards, spend analysis, burn rate, or corporate finance. Triggers on ramp, expenses, transactions, spend, corporate card, burn rate.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tags:
|
|
6
|
+
- ramp
|
|
7
|
+
- finance
|
|
8
|
+
- integration
|
|
9
|
+
- expenses
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Ramp
|
|
13
|
+
|
|
14
|
+
Corporate spend management via Ramp API. No OAuth needed — API key auth.
|
|
15
|
+
|
|
16
|
+
## Setup
|
|
17
|
+
|
|
18
|
+
User needs a Ramp API key from their Ramp dashboard (Settings > Developer API).
|
|
19
|
+
|
|
20
|
+
Store locally (default):
|
|
21
|
+
```bash
|
|
22
|
+
mkdir -p ~/.atris/secrets/ramp
|
|
23
|
+
read -s -p "Ramp API key: " key
|
|
24
|
+
printf '%s' "$key" > ~/.atris/secrets/ramp/API_KEY
|
|
25
|
+
chmod 600 ~/.atris/secrets/ramp/API_KEY
|
|
26
|
+
unset key
|
|
27
|
+
echo "Saved."
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The key is available at runtime as `RAMP_API_KEY` env var.
|
|
31
|
+
|
|
32
|
+
## API Reference
|
|
33
|
+
|
|
34
|
+
Base URL: `https://api.ramp.com/developer/v1`
|
|
35
|
+
|
|
36
|
+
Auth header: `Authorization: Bearer $RAMP_API_KEY`
|
|
37
|
+
|
|
38
|
+
All responses are JSON. List endpoints support `start` (cursor) and `page_size` params for pagination.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Transactions
|
|
43
|
+
|
|
44
|
+
### List Transactions
|
|
45
|
+
```bash
|
|
46
|
+
curl -s "https://api.ramp.com/developer/v1/transactions?page_size=50" \
|
|
47
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Filter params:
|
|
51
|
+
- `from_date` / `to_date` — ISO 8601 (e.g. `2026-03-01`)
|
|
52
|
+
- `department_id` — filter by department
|
|
53
|
+
- `merchant_id` — filter by merchant
|
|
54
|
+
- `user_id` — filter by cardholder
|
|
55
|
+
- `min_amount` / `max_amount` — in cents
|
|
56
|
+
- `state` — PENDING, CLEARED, DECLINED
|
|
57
|
+
|
|
58
|
+
### Get Transaction
|
|
59
|
+
```bash
|
|
60
|
+
curl -s "https://api.ramp.com/developer/v1/transactions/{transaction_id}" \
|
|
61
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Cards
|
|
67
|
+
|
|
68
|
+
### List Cards
|
|
69
|
+
```bash
|
|
70
|
+
curl -s "https://api.ramp.com/developer/v1/cards?page_size=50" \
|
|
71
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Get Card
|
|
75
|
+
```bash
|
|
76
|
+
curl -s "https://api.ramp.com/developer/v1/cards/{card_id}" \
|
|
77
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Create Virtual Card
|
|
81
|
+
```bash
|
|
82
|
+
curl -s -X POST "https://api.ramp.com/developer/v1/cards/deferred/virtual" \
|
|
83
|
+
-H "Authorization: Bearer $RAMP_API_KEY" \
|
|
84
|
+
-H "Content-Type: application/json" \
|
|
85
|
+
-d '{
|
|
86
|
+
"display_name": "Marketing Q1",
|
|
87
|
+
"user_id": "USER_ID",
|
|
88
|
+
"spending_restrictions": {
|
|
89
|
+
"amount": 500000,
|
|
90
|
+
"interval": "MONTHLY",
|
|
91
|
+
"lock_date": null,
|
|
92
|
+
"categories": []
|
|
93
|
+
}
|
|
94
|
+
}'
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Update Card (limits, name, owner)
|
|
98
|
+
```bash
|
|
99
|
+
curl -s -X PATCH "https://api.ramp.com/developer/v1/cards/{card_id}" \
|
|
100
|
+
-H "Authorization: Bearer $RAMP_API_KEY" \
|
|
101
|
+
-H "Content-Type: application/json" \
|
|
102
|
+
-d '{
|
|
103
|
+
"display_name": "New Name",
|
|
104
|
+
"spending_restrictions": {"amount": 100000, "interval": "MONTHLY"}
|
|
105
|
+
}'
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Suspend Card
|
|
109
|
+
```bash
|
|
110
|
+
curl -s -X POST "https://api.ramp.com/developer/v1/cards/{card_id}/deferred/suspension" \
|
|
111
|
+
-H "Authorization: Bearer $RAMP_API_KEY" \
|
|
112
|
+
-H "Content-Type: application/json" \
|
|
113
|
+
-d '{}'
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Terminate Card
|
|
117
|
+
```bash
|
|
118
|
+
curl -s -X POST "https://api.ramp.com/developer/v1/cards/{card_id}/deferred/termination" \
|
|
119
|
+
-H "Authorization: Bearer $RAMP_API_KEY" \
|
|
120
|
+
-H "Content-Type: application/json" \
|
|
121
|
+
-d '{}'
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Company
|
|
127
|
+
|
|
128
|
+
### Get Company Info
|
|
129
|
+
```bash
|
|
130
|
+
curl -s "https://api.ramp.com/developer/v1/business" \
|
|
131
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Get Company Balance
|
|
135
|
+
```bash
|
|
136
|
+
curl -s "https://api.ramp.com/developer/v1/business/balance" \
|
|
137
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Users
|
|
143
|
+
|
|
144
|
+
### List Users
|
|
145
|
+
```bash
|
|
146
|
+
curl -s "https://api.ramp.com/developer/v1/users?page_size=50" \
|
|
147
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Get User
|
|
151
|
+
```bash
|
|
152
|
+
curl -s "https://api.ramp.com/developer/v1/users/{user_id}" \
|
|
153
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## Departments
|
|
159
|
+
|
|
160
|
+
### List Departments
|
|
161
|
+
```bash
|
|
162
|
+
curl -s "https://api.ramp.com/developer/v1/departments" \
|
|
163
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Create Department
|
|
167
|
+
```bash
|
|
168
|
+
curl -s -X POST "https://api.ramp.com/developer/v1/departments" \
|
|
169
|
+
-H "Authorization: Bearer $RAMP_API_KEY" \
|
|
170
|
+
-H "Content-Type: application/json" \
|
|
171
|
+
-d '{"name": "Engineering"}'
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Bills
|
|
177
|
+
|
|
178
|
+
### List Bills
|
|
179
|
+
```bash
|
|
180
|
+
curl -s "https://api.ramp.com/developer/v1/bills?page_size=50" \
|
|
181
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Create Bill
|
|
185
|
+
```bash
|
|
186
|
+
curl -s -X POST "https://api.ramp.com/developer/v1/bills" \
|
|
187
|
+
-H "Authorization: Bearer $RAMP_API_KEY" \
|
|
188
|
+
-H "Content-Type: application/json" \
|
|
189
|
+
-d '{
|
|
190
|
+
"amount": {"amount": 150000, "currency_code": "USD"},
|
|
191
|
+
"vendor_name": "AWS",
|
|
192
|
+
"invoice_number": "INV-001",
|
|
193
|
+
"due_date": "2026-04-01",
|
|
194
|
+
"memo": "March hosting"
|
|
195
|
+
}'
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Reimbursements
|
|
201
|
+
|
|
202
|
+
### List Reimbursements
|
|
203
|
+
```bash
|
|
204
|
+
curl -s "https://api.ramp.com/developer/v1/reimbursements?page_size=50" \
|
|
205
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## Cashbacks
|
|
211
|
+
|
|
212
|
+
### List Cashback Payments
|
|
213
|
+
```bash
|
|
214
|
+
curl -s "https://api.ramp.com/developer/v1/cashbacks?page_size=50" \
|
|
215
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## Accounting
|
|
221
|
+
|
|
222
|
+
### List GL Accounts
|
|
223
|
+
```bash
|
|
224
|
+
curl -s "https://api.ramp.com/developer/v1/accounting/accounts" \
|
|
225
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### List Vendors
|
|
229
|
+
```bash
|
|
230
|
+
curl -s "https://api.ramp.com/developer/v1/accounting/vendors" \
|
|
231
|
+
-H "Authorization: Bearer $RAMP_API_KEY"
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Workflows
|
|
237
|
+
|
|
238
|
+
### "What are we spending on?"
|
|
239
|
+
1. Pull transactions: `GET /transactions?from_date=2026-03-01&to_date=2026-03-31`
|
|
240
|
+
2. Group by merchant name
|
|
241
|
+
3. Sort by total amount descending
|
|
242
|
+
4. Report top 10 merchants and total spend
|
|
243
|
+
|
|
244
|
+
### "Monthly burn rate"
|
|
245
|
+
1. Pull transactions for last 3 months
|
|
246
|
+
2. Sum cleared transactions per month
|
|
247
|
+
3. Calculate average monthly spend
|
|
248
|
+
4. Get company balance: `GET /business/balance`
|
|
249
|
+
5. Runway = balance / average_monthly_burn
|
|
250
|
+
|
|
251
|
+
### "Subscription audit"
|
|
252
|
+
1. Pull 90 days of transactions
|
|
253
|
+
2. Find recurring merchants (same merchant, similar amounts, monthly cadence)
|
|
254
|
+
3. Flag: unused (no logins), duplicate (overlapping tools), expensive (>$500/mo)
|
|
255
|
+
4. Report with recommendation per subscription
|
|
256
|
+
|
|
257
|
+
### "Create a project card"
|
|
258
|
+
1. Find the user: `GET /users` → match by name/email
|
|
259
|
+
2. **Confirm with user: "Create virtual card 'Project X' with $5,000/mo limit for {user}?"**
|
|
260
|
+
3. Create card: `POST /cards/deferred/virtual`
|
|
261
|
+
4. Return card details
|
|
262
|
+
|
|
263
|
+
### "Department spend breakdown"
|
|
264
|
+
1. List departments: `GET /departments`
|
|
265
|
+
2. For each department, pull transactions filtered by `department_id`
|
|
266
|
+
3. Summarize spend per department
|
|
267
|
+
4. Highlight departments over/under budget
|
|
268
|
+
|
|
269
|
+
### "Anomaly detection"
|
|
270
|
+
1. Pull last 30 days of transactions
|
|
271
|
+
2. Calculate per-merchant averages from prior 90 days
|
|
272
|
+
3. Flag transactions >2x the merchant average
|
|
273
|
+
4. Flag new merchants with spend >$500
|
|
274
|
+
5. Flag weekend/holiday transactions
|
|
275
|
+
6. Report anomalies with context
|
|
276
|
+
|
|
277
|
+
## Amounts
|
|
278
|
+
|
|
279
|
+
All monetary amounts in the Ramp API are in **cents** (integer). $150.00 = 15000.
|
|
280
|
+
|
|
281
|
+
## Pagination
|
|
282
|
+
|
|
283
|
+
List endpoints return `{ "data": [...], "page": { "next": "cursor_string" } }`.
|
|
284
|
+
|
|
285
|
+
To get next page: add `?start=cursor_string` to the request.
|
|
286
|
+
|
|
287
|
+
## Rate Limits
|
|
288
|
+
|
|
289
|
+
Ramp applies rate limits per API key. If you get 429, wait and retry with exponential backoff.
|
|
290
|
+
|
|
291
|
+
## Full API Spec
|
|
292
|
+
|
|
293
|
+
For the complete OpenAPI spec: `https://docs.ramp.com/openapi/developer-api.json`
|
|
294
|
+
|
|
295
|
+
For AI-readable docs: `https://docs.ramp.com/llms.txt`
|
package/package.json
CHANGED