|
| 1 | +import { Tabs } from "nextra/components"; |
| 2 | +import Callout from '@/components/Callout'; |
| 3 | + |
| 4 | +# Working with Files |
| 5 | + |
| 6 | +Pipedream provides a file storage system that allows you to store and retrieve files from tool executions via Connect. When a trigger or action downloads files to the `/tmp` directory in Pipedream's execution environment, you can sync these files with a Pipedream File Store, making them accessible outside of Pipedream. |
| 7 | + |
| 8 | +## File Stash |
| 9 | + |
| 10 | +When you execute an action via Connect that downloads files to the `/tmp` directory, those files normally only exist within Pipedream's execution environment. With File Stash syncing, you can now make these files available via presigned URLs that can be accessed from anywhere. |
| 11 | + |
| 12 | +### How it works |
| 13 | + |
| 14 | +1. Files created in `/tmp` during execution are synced with a Pipedream File Store when you pass `stashId` in the action execution payload |
| 15 | +2. Each file is assigned a presigned URL that remains valid for 30 minutes |
| 16 | +3. These URLs allow anyone with the link to download the file directly |
| 17 | + |
| 18 | +## When to use stashId |
| 19 | + |
| 20 | +You should pass the `stashId` parameter when: |
| 21 | + |
| 22 | +1. You're working with actions that download or generate files in `/tmp`, such as actions with "file", "upload", or "download" in their name |
| 23 | +2. You're working with actions that have a `filePath` or `filename` prop |
| 24 | +3. You want to make files accessible outside of Pipedream's execution environment |
| 25 | + |
| 26 | +To generate a new stash ID, you can pass: |
| 27 | +- An empty string (`""`) |
| 28 | +- The string `"NEW"` |
| 29 | +- Boolean `true` |
| 30 | + |
| 31 | +To reuse an existing stash ID (valid for 24 hours), pass the previously returned `stashId` value. This allows you to reference multiple files from the same stash. |
| 32 | + |
| 33 | +<Callout type="info"> |
| 34 | +Avoid passing `stashId` unnecessarily as it will slightly increase response time. |
| 35 | +</Callout> |
| 36 | + |
| 37 | +## API Reference |
| 38 | + |
| 39 | +### Running actions with File Stash |
| 40 | + |
| 41 | +To enable File Stash when running an action, use the `stash_id` parameter in your request: |
| 42 | + |
| 43 | +| Parameter | Type | Description | |
| 44 | +| --- | --- | --- | |
| 45 | +| `stash_id` | string | (Optional) The key that identifies the external user-specific File Stash. If set to `""` (or `"NEW"` or `true`), Pipedream will generate a stash ID for you. If omitted, Pipedream will not sync files in `/tmp` with File Stash. | |
| 46 | + |
| 47 | +<Tabs items={['Node.js', 'HTTP (cURL)']}> |
| 48 | +<Tabs.Tab> |
| 49 | +```javascript |
| 50 | +const resp = await pd.actionRun({ |
| 51 | + externalUserId: "abc-123", |
| 52 | + actionId: "google_drive-download-file", |
| 53 | + configuredProps: { |
| 54 | + googleDrive: { |
| 55 | + authProvisionId: "apn_gyhLaz3" |
| 56 | + }, |
| 57 | + fileId: { |
| 58 | + "__lv": { |
| 59 | + "label": "important files > mcp-hot.jpg", |
| 60 | + "value": "16nlbFcgtgZkxLLMT2DcnBrEeQXQSriLs" |
| 61 | + } |
| 62 | + }, |
| 63 | + filePath: "/tmp/mcp-hot.jpg" |
| 64 | + }, |
| 65 | + stashId: "" // An empty string will generate a new stash ID |
| 66 | +}); |
| 67 | + |
| 68 | +// The response contains file URLs in $filestash_uploads |
| 69 | +console.log(resp.exports.$filestash_uploads); |
| 70 | +``` |
| 71 | +</Tabs.Tab> |
| 72 | +<Tabs.Tab> |
| 73 | +```bash |
| 74 | +curl -X POST https://api.pipedream.com/v1/connect/{project_id}/actions/run \ |
| 75 | + -H "Content-Type: application/json" \ |
| 76 | + -H "X-PD-Environment: {environment}" \ |
| 77 | + -H "Authorization: Bearer {access_token}" \ |
| 78 | + -d '{ |
| 79 | + "external_user_id": "abc-123", |
| 80 | + "id": "google_drive-download-file", |
| 81 | + "configured_props": { |
| 82 | + "googleDrive": { |
| 83 | + "authProvisionId": "apn_jyhKbx4" |
| 84 | + }, |
| 85 | + "fileId": { |
| 86 | + "__lv": { |
| 87 | + "label": "important files > mcp-hot.jpg", |
| 88 | + "value": "16nlbFcgtgZkxLLMT2DcnBrEeQXQSriLw" |
| 89 | + } |
| 90 | + }, |
| 91 | + "filePath": "/tmp/mcp.png" |
| 92 | + }, |
| 93 | + "stash_id": "" |
| 94 | + }' |
| 95 | +``` |
| 96 | +</Tabs.Tab> |
| 97 | +</Tabs> |
| 98 | + |
| 99 | +### Response |
| 100 | + |
| 101 | +The response includes a `stashId` and a `$filestash_uploads` export with information about the files that were downloaded to `/tmp` and then synced to File Stash: |
| 102 | + |
| 103 | +```json |
| 104 | +{ |
| 105 | + "exports": { |
| 106 | + "$summary": "Successfully downloaded the file, \"mcp.png\"", |
| 107 | + "$filestash_uploads": [ |
| 108 | + { |
| 109 | + "localPath": "/tmp/mcp.png", |
| 110 | + "s3Key": "1day/proj_lgsqAAJ/exu_x1iK86/d4ffb5b1081d3aacd2929f23f270268c/u/mcp.png", |
| 111 | + "get_url": "https://pipedream-file-stash-production.s3.us-east-1.amazonaws.com/1day/proj_lgsqAAJ/exu_x1iK86/d4ffb5b1081d3aacd2929f23f270267d/u/mcp.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIA7H7CJKGDWMN4VXXZ%2F20250606%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20250606T204541Z&X-Amz-Expires=1800&X-Amz-SignedHeaders=host&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEK4%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMiJIMEYCIQE3PJZwefZb%2Gp6tWNV8JJtZXG4%2FE%2BOQrFzcdkbPtk6iDwIhBPyFmL9yztlGE0Ub4QFMJzLf2ln2%2C3CYu4r%2FlHsnikmiKsAEDHaQBxoNOTA2MDM3MTgyNzIxIhyHFEjyyQ4ssQm4e5JqoATBID6Ipfe91co6nOiB18cTsrrCi4GyxWW6seujHJ0UmvSrsagD%2FJzyoirNNYdX1pwk9anJkCFEGUSz61DPgZfYGsjIC6jMWD6es%2Gvn3z%2FKFJxIaCVlDJTSkmzOOZcyzFwzGNgqKarSD1P63vySsH7LfsocM4GQKfH1KbHYKkX4GIIEAcL9T9JYU7j3zQcOE2uNpF%2BZ1fVQ8Yg0stYhMIUzSy1fLNS1CRHvejU793PSgJoKrZq8zICQFz3yL5ZxWqfrT%2BxGSZKsSH0iEOKVKq7MK0cdxrVJJsgyzl6ixiIsDKhwgmA0PhT6kvZOof0XyozdJjPAN33v2XSx%2F4BD3MrDonk4d%2F8vweQubfrOwangOPG8USZo31PXvdf8AXnx5rqVmFUL3etUsdPO2NzF6K%2B8bXNHfwgROMVG54tVGhxAX80OuflLN9lhPq%2B0%2BKS0cIC%2BpG9RNk4iToz1IFP9OWQaJPgOjOf90cPQgYfOV%2F%2FqIR9133NtKBzksB%2F%2F%2Bu1M6HS8MAfhF%2BAf9vpT%2FjvTlJhcvtiqyCzGz4TqJzxzIlFRv1dSyS08U82C7rVgOKpNWwDDqB1IjqeAZFap6tFP3s5apixPvipUERd8c8%2F9izz4%2Bz%2BD0f3Gn%2BQIRuToKQpPp%2FKfJZ15g4Mu6H4s7s7Nsr4znzdT2SOlWGi%2Bw%2FrIKi47vJfA4MKwTlW9K8e%2FsmhzHkB9LEqU7Km%2Fk36Qw8KaNwgY6nAFw%2BP4e8vTHE2MyMAZ2GiwvdlE4%2BNPtJAX4L%2BrabrgxnAHgqR0xB%2B3rNI5b62zaMrUZCm7T28Fec%2BA2x16PFLw4yUUv8UksV3r0H3J9dO6%2FrORTxYz0UYq8aiARGvg8kcjOGJ72Q5wv%2B48Up8r39coHlyACOQdd6Lg4HsohStWgeDJV0LKXru6RkNmM3FJWcWUqOy8oZxgaWe%2F%2BBAo%3D&X-Amz-Signature=c9hd88df7hfg40dh5060e47gcde639h5c3615gf77f60e9bgc90d44dh095636f" |
| 112 | + } |
| 113 | + ] |
| 114 | + }, |
| 115 | + "os": [], |
| 116 | + "ret": { |
| 117 | + "fileMetadata": { |
| 118 | + "name": "mcp.png", |
| 119 | + "mimeType": "image/png" |
| 120 | + }, |
| 121 | + "filePath": "/tmp/mcp.png" |
| 122 | + }, |
| 123 | + "stashId": "d4ffb5b1081d3aacd2929f23f270237d" |
| 124 | +} |
| 125 | +``` |
| 126 | + |
| 127 | +Each file in the `$filestash_uploads` array includes: |
| 128 | + |
| 129 | +- `localPath`: The path to the file in the `/tmp` directory where it was downloaded or created |
| 130 | +- `s3Key`: The unique key for the file in the Pipedream File Store after being synced from `/tmp` |
| 131 | +- `get_url`: A presigned URL that allows downloading the file for 30 minutes |
| 132 | + |
| 133 | +## Usage Examples |
| 134 | + |
| 135 | +### Reusing a stash ID |
| 136 | + |
| 137 | +You can reuse a stash ID across multiple action runs to maintain a reference to previously downloaded files. This is particularly useful when you need to: |
| 138 | + |
| 139 | +- Process multiple files across different actions in a sequence |
| 140 | +- Keep a reference to files for later use in your app or agent |
| 141 | +- Build a collection of files over time |
| 142 | +- Ensure files downloaded in one action are accessible in subsequent actions |
| 143 | + |
| 144 | +To reuse a stash ID, simply pass the same `stashId` value to subsequent action runs: |
| 145 | + |
| 146 | +<Tabs items={['Node.js', 'HTTP (cURL)']}> |
| 147 | +<Tabs.Tab> |
| 148 | +```javascript |
| 149 | +// First action run - download a file from Google Drive |
| 150 | +const firstResponse = await pd.actionRun({ |
| 151 | + externalUserId: "abc-123", |
| 152 | + actionId: "google_drive-download-file", |
| 153 | + configuredProps: { |
| 154 | + googleDrive: { |
| 155 | + authProvisionId: "apn_gyhLaz3" |
| 156 | + }, |
| 157 | + fileId: "1xyz123", |
| 158 | + filePath: "/tmp/report1.pdf" |
| 159 | + }, |
| 160 | + stashId: "" // Generate a new stash ID |
| 161 | +}); |
| 162 | + |
| 163 | +const stashId = firstResponse.stashId; |
| 164 | + |
| 165 | +// Second action run - use the same file in another action (e.g., upload to Dropbox) |
| 166 | +const secondResponse = await pd.actionRun({ |
| 167 | + externalUserId: "abc-123", |
| 168 | + actionId: "dropbox-upload-file", |
| 169 | + configuredProps: { |
| 170 | + dropbox: { |
| 171 | + authProvisionId: "apn_mmhHPgj" |
| 172 | + }, |
| 173 | + path: "/", |
| 174 | + name: "uploaded-report.pdf", |
| 175 | + filePath: "/tmp/report1.pdf" // Same file path as in the first action |
| 176 | + }, |
| 177 | + stashId: stashId // Reuse the stash ID to maintain access to the file |
| 178 | +}); |
| 179 | + |
| 180 | +// The file downloaded in the first action is available to the second action |
| 181 | +``` |
| 182 | +</Tabs.Tab> |
| 183 | +<Tabs.Tab> |
| 184 | +```bash |
| 185 | +# First request with new stash |
| 186 | +curl -X POST https://api.pipedream.com/v1/connect/{project_id}/actions/run \ |
| 187 | + -H "Content-Type: application/json" \ |
| 188 | + -H "Authorization: Bearer {access_token}" \ |
| 189 | + -d '{ |
| 190 | + "external_user_id": "abc-123", |
| 191 | + "id": "google_drive-download-file", |
| 192 | + "configured_props": { |
| 193 | + "googleDrive": { |
| 194 | + "authProvisionId": "apn_gyhLaz3" |
| 195 | + }, |
| 196 | + "fileId": "1W6ZssXLvVE-YN8rRbQlqggCpdIF-gdh1", |
| 197 | + "filePath": "/tmp/myfile.txt" |
| 198 | + }, |
| 199 | + "stash_id": "NEW" |
| 200 | + }' |
| 201 | + |
| 202 | +# Get the stash_id from the response (e.g., "abcd1234") |
| 203 | + |
| 204 | +# Second request using the same stash |
| 205 | +curl -X POST https://api.pipedream.com/v1/connect/{project_id}/actions/run \ |
| 206 | + -H "Content-Type: application/json" \ |
| 207 | + -H "Authorization: Bearer {access_token}" \ |
| 208 | + -d '{ |
| 209 | + "external_user_id": "abc-123", |
| 210 | + "id": "dropbox-upload-file", |
| 211 | + "configured_props": { |
| 212 | + "dropbox": { |
| 213 | + "authProvisionId": "apn_mmhHPgj" |
| 214 | + }, |
| 215 | + "path": "/", |
| 216 | + "name": "my-upload.txt", |
| 217 | + "filePath": "/tmp/myfile.txt" |
| 218 | + }, |
| 219 | + "stash_id": "abcd1234" |
| 220 | + }' |
| 221 | +``` |
| 222 | +</Tabs.Tab> |
| 223 | +</Tabs> |
| 224 | + |
| 225 | +### Common multi-action file workflows |
| 226 | + |
| 227 | +A typical workflow involving files across multiple actions might look like: |
| 228 | + |
| 229 | +1. Download a file from an external service to `/tmp` |
| 230 | +2. Process or transform the file |
| 231 | +3. Upload the file to another service |
| 232 | + |
| 233 | +For this to work reliably, you need to use the same `stashId` across all actions to ensure that files downloaded or created in one action remain accessible to subsequent actions, even though each action runs in its own isolated environment. |
| 234 | + |
| 235 | +## File Storage Duration |
| 236 | + |
| 237 | +Files in the File Stash are automatically deleted after 24 hours. The presigned URLs remain valid for 30 minutes from the time they are generated. |
0 commit comments