|
| 1 | +# Sandbox lifecycle webhooks |
| 2 | + |
| 3 | +Webhooks provide a way for notifications to be delivered to an external web server whenever certain sandbox lifecycle events occur. |
| 4 | +This allows you to receive real-time updates about sandbox creation, updates, and termination without having to poll the API. |
| 5 | +All webhook requests require authentication using your team [API key](/docs/api-key#where-to-find-api-key). |
| 6 | + |
| 7 | +## Webhook management |
| 8 | + |
| 9 | +### Register webhook |
| 10 | + |
| 11 | +Register a new webhook to receive sandbox lifecycle events. |
| 12 | +The webhook will be registered for the team ID associated with your API key. You will receive webhook notifications for sandbox lifecycle events from sandboxes created by your team with the [following payload](#webhook-payload). |
| 13 | + |
| 14 | + |
| 15 | +<CodeGroup> |
| 16 | +```js |
| 17 | +// Register a new webhook |
| 18 | +const resp = await fetch( |
| 19 | + 'https://api.e2b.app/events/webhooks/sandboxes', |
| 20 | + { |
| 21 | + method: 'POST', |
| 22 | + headers: { |
| 23 | + 'X-API-Key': E2B_API_KEY, |
| 24 | + 'Content-Type': 'application/json', |
| 25 | + }, |
| 26 | + body: JSON.stringify({ |
| 27 | + url: 'https://your-webhook-endpoint.com/webhook', |
| 28 | + events: ['create', 'kill', 'update'] |
| 29 | + }), |
| 30 | + } |
| 31 | +) |
| 32 | + |
| 33 | +if (resp.status === 201) { |
| 34 | + console.log('Webhook registered successfully') |
| 35 | +} |
| 36 | +``` |
| 37 | +```python |
| 38 | +import requests |
| 39 | + |
| 40 | +# Register a new webhook |
| 41 | +resp = requests.post( |
| 42 | + "https://api.e2b.app/events/webhooks/sandboxes", |
| 43 | + headers={ |
| 44 | + "X-API-Key": E2B_API_KEY, |
| 45 | + "Content-Type": "application/json", |
| 46 | + }, |
| 47 | + json={ |
| 48 | + "url": "https://your-webhook-endpoint.com/webhook", |
| 49 | + "events": ["create", "kill", "update"] |
| 50 | + } |
| 51 | +) |
| 52 | + |
| 53 | +if resp.status_code == 201: |
| 54 | + print("Webhook registered successfully") |
| 55 | +``` |
| 56 | +</CodeGroup> |
| 57 | + |
| 58 | + |
| 59 | +### Get webhook configuration |
| 60 | + |
| 61 | +Retrieve the current webhook configuration for your team. |
| 62 | + |
| 63 | +<CodeGroup> |
| 64 | +```js |
| 65 | +// Get current webhook configuration |
| 66 | +const resp = await fetch( |
| 67 | + 'https://api.e2b.app/events/webhooks/sandboxes', |
| 68 | + { |
| 69 | + method: 'GET', |
| 70 | + headers: { |
| 71 | + 'X-API-Key': E2B_API_KEY, |
| 72 | + }, |
| 73 | + } |
| 74 | +) |
| 75 | +const webhookConfig = await resp.json() |
| 76 | +console.log(webhookConfig) |
| 77 | +// { |
| 78 | +// "teamID": "<your-team-id>", |
| 79 | +// "url": "https://your-webhook-endpoint.com/webhook", |
| 80 | +// "events": ["create", "kill"] |
| 81 | +// } |
| 82 | + |
| 83 | +``` |
| 84 | +```python |
| 85 | +import requests |
| 86 | + |
| 87 | +# Get current webhook configuration |
| 88 | +resp = requests.get( |
| 89 | + "https://api.e2b.app/events/webhooks/sandboxes", |
| 90 | + headers={ |
| 91 | + "X-API-Key": E2B_API_KEY, |
| 92 | + } |
| 93 | +) |
| 94 | + |
| 95 | +webhook_config = resp.json() |
| 96 | +print(webhook_config) |
| 97 | +# { |
| 98 | +# "teamID": "<your-team-id>", |
| 99 | +# "events": ["create", "kill"] |
| 100 | +# "url": "https://your-webhook-endpoint.com/webhook", |
| 101 | +# } |
| 102 | +``` |
| 103 | +</CodeGroup> |
| 104 | + |
| 105 | +### Update webhook configuration |
| 106 | + |
| 107 | +Update an existing webhook configuration. The update will replace the previous configuration fields with provided fields. |
| 108 | + |
| 109 | +<CodeGroup> |
| 110 | +```js |
| 111 | +// Update webhook configuration |
| 112 | +const resp = await fetch( |
| 113 | + 'https://api.e2b.app/events/webhooks/sandboxes', |
| 114 | + { |
| 115 | + method: 'PATCH', |
| 116 | + headers: { |
| 117 | + 'X-API-Key': E2B_API_KEY, |
| 118 | + 'Content-Type': 'application/json', |
| 119 | + }, |
| 120 | + body: JSON.stringify({ |
| 121 | + url: 'https://your-updated-webhook-endpoint.com/webhook', |
| 122 | + events: ['create'] |
| 123 | + }), |
| 124 | + } |
| 125 | +) |
| 126 | + |
| 127 | +const updatedWebhookConfig = await resp.json() |
| 128 | +console.log(updatedWebhookConfig) |
| 129 | +// { |
| 130 | +// "teamID": "<your-team-id>", |
| 131 | +// "events": ["create"], |
| 132 | +// "url": "https://your-updated-webhook-endpoint.com/webhook" |
| 133 | +// } |
| 134 | +``` |
| 135 | +```python |
| 136 | +import requests |
| 137 | + |
| 138 | +# Update webhook configuration |
| 139 | +resp = requests.patch( |
| 140 | + "https://api.e2b.app/events/webhooks/sandboxes", |
| 141 | + headers={ |
| 142 | + "X-API-Key": E2B_API_KEY, |
| 143 | + "Content-Type": "application/json", |
| 144 | + }, |
| 145 | + json={ |
| 146 | + "url": "https://your-updated-webhook-endpoint.com/webhook", |
| 147 | + "events": ["create"] |
| 148 | + } |
| 149 | +) |
| 150 | + |
| 151 | +updated_webhook_config = resp.json() |
| 152 | +print(updated_webhook_config) |
| 153 | +# { |
| 154 | +# "teamID": "<your-team-id>", |
| 155 | +# "events": ["create"], |
| 156 | +# "url": "https://your-updated-webhook-endpoint.com/webhook" |
| 157 | +# } |
| 158 | +``` |
| 159 | +</CodeGroup> |
| 160 | + |
| 161 | +### Delete webhook |
| 162 | + |
| 163 | +Unregister the webhook. |
| 164 | + |
| 165 | +<CodeGroup> |
| 166 | +```js |
| 167 | +// Delete webhook configuration |
| 168 | +const resp = await fetch( |
| 169 | + 'https://api.e2b.app/events/webhooks/sandboxes', |
| 170 | + { |
| 171 | + method: 'DELETE', |
| 172 | + headers: { |
| 173 | + 'X-API-Key': E2B_API_KEY, |
| 174 | + }, |
| 175 | + } |
| 176 | +) |
| 177 | + |
| 178 | +if (resp.status === 200) { |
| 179 | + console.log('Webhook deleted successfully') |
| 180 | +} |
| 181 | +``` |
| 182 | +```python |
| 183 | +import requests |
| 184 | + |
| 185 | +# Delete webhook configuration |
| 186 | +resp = requests.delete( |
| 187 | + "https://api.e2b.app/events/webhooks/sandboxes", |
| 188 | + headers={ |
| 189 | + "X-API-Key": E2B_API_KEY, |
| 190 | + } |
| 191 | +) |
| 192 | + |
| 193 | +if resp.status_code == 200: |
| 194 | + print("Webhook deleted successfully") |
| 195 | +``` |
| 196 | +</CodeGroup> |
| 197 | + |
| 198 | +### Test webhook |
| 199 | + |
| 200 | +Send a test webhook to verify your endpoint is working correctly. |
| 201 | + |
| 202 | +<CodeGroup> |
| 203 | +```js |
| 204 | +// Test webhook endpoint |
| 205 | +const resp = await fetch( |
| 206 | + 'https://api.e2b.app/events/webhooks/sandboxes/test', |
| 207 | + { |
| 208 | + method: 'POST', |
| 209 | + headers: { |
| 210 | + 'X-API-Key': E2B_API_KEY, |
| 211 | + }, |
| 212 | + } |
| 213 | +) |
| 214 | + |
| 215 | +if (resp.status === 200) { |
| 216 | + console.log('Test webhook sent successfully') |
| 217 | +} |
| 218 | +``` |
| 219 | +```python |
| 220 | +import requests |
| 221 | + |
| 222 | +# Test webhook endpoint |
| 223 | +resp = requests.post( |
| 224 | + "https://api.e2b.app/events/webhooks/sandboxes/test", |
| 225 | + headers={ |
| 226 | + "X-API-Key": E2B_API_KEY, |
| 227 | + } |
| 228 | +) |
| 229 | + |
| 230 | +if resp.status_code == 200: |
| 231 | + print("Test webhook sent successfully") |
| 232 | +``` |
| 233 | +</CodeGroup> |
| 234 | + |
| 235 | +## Webhook payload |
| 236 | + |
| 237 | +When a webhook is triggered, your endpoint will receive a POST request with a JSON payload containing the sandbox event data. The payload structure matches the event format from the API: |
| 238 | + |
| 239 | +```json |
| 240 | +{ |
| 241 | + "eventCategory": "lifecycle", |
| 242 | + "eventData": { |
| 243 | + "sandbox_metadata": { |
| 244 | + "<custom-key>": "<custom-value>" |
| 245 | + } |
| 246 | + }, |
| 247 | + "eventLabel": "create", |
| 248 | + "sandboxBuildId": "a979a14b-bdcc-49e6-bc04-1189fc9fe7c2", |
| 249 | + "sandboxExecutionId": "1dae9a1c-9957-4ce7-a236-a99d5779aadf", |
| 250 | + "sandboxId": "<your-sandbox-id>", |
| 251 | + "sandboxTeamId": "<your-team-id>", |
| 252 | + "sandboxTemplateId": "rki5dems9wqfm4r03t7g", |
| 253 | + "timestamp": "2025-08-06T20:59:24Z" |
| 254 | +} |
| 255 | +``` |
| 256 | + |
| 257 | +## Available event types |
| 258 | + |
| 259 | +The following event types can be subscribed to via webhooks, they are used as the `eventLabel` field in the [payload](#webhook-payload). |
| 260 | + |
| 261 | +- `create` - Sandbox creation |
| 262 | +- `kill` - Sandbox termination |
| 263 | +- `update` - Sandbox configuration updates |
| 264 | +- `pause` - Sandbox pausing |
| 265 | +- `resume` - Sandbox resuming |
| 266 | + |
| 267 | + |
0 commit comments