linq-python 0.41.0__py3-none-any.whl → 0.41.2__py3-none-any.whl
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.
- linq/_client.py +228 -114
- linq/_version.py +1 -1
- linq/resources/attachments.py +62 -22
- linq/resources/chats/chats.py +192 -144
- linq/resources/chats/messages.py +32 -24
- linq/resources/chats/polls.py +32 -24
- linq/resources/messages/messages.py +128 -96
- linq/resources/messages/poll.py +32 -24
- linq/types/attachment_create_response.py +5 -3
- {linq_python-0.41.0.dist-info → linq_python-0.41.2.dist-info}/METADATA +1 -1
- {linq_python-0.41.0.dist-info → linq_python-0.41.2.dist-info}/RECORD +13 -13
- {linq_python-0.41.0.dist-info → linq_python-0.41.2.dist-info}/WHEEL +0 -0
- {linq_python-0.41.0.dist-info → linq_python-0.41.2.dist-info}/licenses/LICENSE +0 -0
linq/_client.py
CHANGED
|
@@ -186,35 +186,39 @@ class LinqAPIV3(SyncAPIClient):
|
|
|
186
186
|
|
|
187
187
|
## Ephemeral Messages (Privacy Tier)
|
|
188
188
|
|
|
189
|
-
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is
|
|
189
|
+
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is given a **retention window configured for your account**. After that window, the message's text, formatting, and attachment references are no longer retrievable through the API — see the Attachments row below for how the attachment media itself is handled. Metadata about the message is retained: message identifiers, timestamps, phone numbers, and delivery state. Metadata retention is not bounded by this window. Bounded operational copies, such as backups and delivery queues, expire on their own separate schedules. There is no per-message flag; ephemerality is applied automatically based on your configuration.
|
|
190
|
+
|
|
191
|
+
The window can be set anywhere from **60 minutes to 24 hours**, and defaults to **24 hours**. Ask your Linq support contact to configure a shorter window; it cannot be changed through the API.
|
|
190
192
|
|
|
191
193
|
You can request it at two scopes:
|
|
192
194
|
|
|
193
195
|
| Scope | Effect |
|
|
194
196
|
|---|---|
|
|
195
|
-
| **Partner-wide** | Every outbound and inbound message on every phone number under your account
|
|
196
|
-
| **Per phone number** | Only the specified phone numbers have
|
|
197
|
+
| **Partner-wide** | Every outbound and inbound message on every phone number under your account has its content removed from the API surface after your configured window. Metadata is retained. |
|
|
198
|
+
| **Per phone number** | Only the specified phone numbers have message content removed from the API surface this way. The rest follow the standard message-retention policy. |
|
|
197
199
|
|
|
198
200
|
**Behavioral differences vs the standard default:**
|
|
199
201
|
|
|
200
202
|
| Aspect | Standard | Ephemeral |
|
|
201
203
|
|---|---|---|
|
|
202
|
-
| Retention | Retained per the standard message-retention policy | **Hard backstop: 24 hours
|
|
203
|
-
| After expiry | Message stays retrievable | Message is
|
|
204
|
-
| Content on expiry | N/A | Text, formatting, and attachment references are
|
|
204
|
+
| Retention | Retained per the standard message-retention policy | **Hard backstop: your configured window** (60 minutes – 24 hours, default 24 hours) from when the message is created |
|
|
205
|
+
| After expiry | Message stays retrievable | Message content is no longer retrievable — `GET /v3/messages/{messageId}` returns `404` and it no longer appears in `GET /v3/chats/{chatId}/messages` |
|
|
206
|
+
| Content on expiry | N/A | Text, formatting, and attachment references are removed from the API surface, not blanked out in place. Metadata (identifiers, timestamps, phone numbers, delivery state) is retained; its retention is not bounded by this window |
|
|
207
|
+
| Attachments | Retained | Media sent on the **ephemeral attachments tier** is removed on its own storage backstop — within roughly 24–48 hours of upload — independently of the message window, so it can outlast a window shorter than a day. Attachments on the persistent tier (including pre-uploads via `POST /v3/attachments`) are kept until you `DELETE` them |
|
|
205
208
|
| Cross-partner isolation | Enforced | Enforced |
|
|
206
209
|
|
|
207
|
-
**How the
|
|
210
|
+
**How the retention window works:**
|
|
208
211
|
|
|
209
|
-
- The window
|
|
210
|
-
-
|
|
212
|
+
- The window runs from **message creation** (`created_at`). It is configured for your account (60 minutes – 24 hours, default 24 hours) and cannot be set per message.
|
|
213
|
+
- Attachment media follows its own storage backstop rather than the message window — see the Attachments row above.
|
|
211
214
|
- Expiry is delivery-independent — the clock starts when the message is created, not when it is delivered or read.
|
|
215
|
+
- **Deletion happens shortly *after* the window, not exactly at it.** A background sweep runs every ~5 minutes, so a message typically stops being retrievable within about 5 minutes of its expiry, and longer while a backlog is being worked through. Treat the window as the guaranteed *minimum* retention, never as an exact deletion time or an upper bound.
|
|
212
216
|
|
|
213
217
|
**What you observe:**
|
|
214
218
|
|
|
215
|
-
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time.
|
|
219
|
+
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time, and they do not report your configured window either — so if you are on a window shorter than 24 hours you cannot derive a message's expiry from the API today. Track the window you agreed with your Linq support contact and compute `created_at + window` yourself.
|
|
216
220
|
- **No deletion webhook is sent.** There is no `message.deleted` event — a message simply stops being retrievable once its window passes.
|
|
217
|
-
- **The backstop
|
|
221
|
+
- **The attachment backstop is separate from the message window.** API retrievability (the `404` behavior above) ends at your configured window. Ephemeral-tier media objects are removed on their own storage backstop — within roughly 24–48 hours of upload — which is independent of the message window and can outlast a window shorter than a day. Removal of the corresponding entries from the sending device happens asynchronously and can complete after the backstop.
|
|
218
222
|
- **Delivery is unaffected.** Ephemeral messages send, deliver, and fire the usual `message.sent` / `message.received` and status webhooks exactly like standard messages. Only retention changes.
|
|
219
223
|
|
|
220
224
|
**When to choose ephemeral:**
|
|
@@ -223,7 +227,7 @@ class LinqAPIV3(SyncAPIClient):
|
|
|
223
227
|
- The conversation is high-sensitivity (PHI, financial, identity verification) and you do not want it sitting in storage long-term.
|
|
224
228
|
- Your application is the system of record — you capture what you need from the delivery webhook in real time and do not rely on reading message history back from Linq later.
|
|
225
229
|
|
|
226
|
-
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message
|
|
230
|
+
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message once its window passes, persist anything you need to keep from the webhook payload at the time it is delivered.
|
|
227
231
|
"""
|
|
228
232
|
from .resources.messages import MessagesResource
|
|
229
233
|
|
|
@@ -257,13 +261,28 @@ class LinqAPIV3(SyncAPIClient):
|
|
|
257
261
|
- **Reduce message send latency** — the file is already stored, so sending is faster
|
|
258
262
|
|
|
259
263
|
**How it works:**
|
|
260
|
-
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a
|
|
264
|
+
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a reusable `attachment_id`
|
|
261
265
|
2. PUT the raw file bytes to the `upload_url` with the `required_headers` (no JSON or multipart — just the binary content)
|
|
262
|
-
3. Reference the `attachment_id` in your media part when sending messages (
|
|
266
|
+
3. Reference the `attachment_id` in your media part when sending messages (stays valid unless deleted — see [Attachment Lifetime](#attachment-lifetime))
|
|
263
267
|
|
|
264
268
|
**Key difference:** When you provide an external `url`, we download and process the file on every send.
|
|
265
269
|
When you use a pre-uploaded `attachment_id`, the file is already stored — so repeated sends skip the download step entirely.
|
|
266
270
|
|
|
271
|
+
## Attachment Lifetime
|
|
272
|
+
|
|
273
|
+
An `attachment_id` and its CDN URL stay valid until the file is deleted. Three things delete it:
|
|
274
|
+
|
|
275
|
+
| Trigger | Applies to |
|
|
276
|
+
|---|---|
|
|
277
|
+
| `DELETE /v3/attachments/{attachmentId}` | Any attachment you own |
|
|
278
|
+
| Ephemeral **attachments** tier (24–48h storage backstop) | Attachments on ephemeral-tier partners or phone numbers |
|
|
279
|
+
| Ephemeral **messages** tier | Does **not** remove attachment bytes on its own: ephemeral-tier objects are removed by the 24–48h storage backstop above, and persistent-tier attachments are kept until you `DELETE` them explicitly. |
|
|
280
|
+
|
|
281
|
+
Deletion is not reversible, and there is no `attachment.deleted` webhook. On either
|
|
282
|
+
ephemeral tier, download anything you need to keep when you receive it rather than
|
|
283
|
+
re-fetching later, and do not assume a pre-uploaded `attachment_id` can be reused
|
|
284
|
+
indefinitely.
|
|
285
|
+
|
|
267
286
|
## Domain Allowlisting
|
|
268
287
|
|
|
269
288
|
Attachment URLs in API responses are served from `cdn.linqapp.com`. This includes:
|
|
@@ -314,7 +333,7 @@ class LinqAPIV3(SyncAPIClient):
|
|
|
314
333
|
|
|
315
334
|
| Tier | URL pattern | TTL |
|
|
316
335
|
|---|---|---|
|
|
317
|
-
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived |
|
|
336
|
+
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived — the URL itself does not expire, but see [Attachment Lifetime](#attachment-lifetime) |
|
|
318
337
|
| Ephemeral | Pre-signed URL pointing at the ephemeral prefix on `cdn.linqapp.com` | 15 minutes per signed URL — re-fetch via the API for a fresh URL |
|
|
319
338
|
|
|
320
339
|
Inbound media you receive over webhooks uses the same layout your outbound sends produce, so the URL you store and the URL you build look identical — no special casing in your client.
|
|
@@ -333,7 +352,7 @@ class LinqAPIV3(SyncAPIClient):
|
|
|
333
352
|
| Aspect | Persistent | Ephemeral |
|
|
334
353
|
|---|---|---|
|
|
335
354
|
| Download URL form | Long-lived CDN URL | Pre-signed URL with short TTL |
|
|
336
|
-
| Retention floor |
|
|
355
|
+
| Retention floor | Until you call `DELETE` | **Hard backstop: 24–48h** — even without an explicit `DELETE`, the platform removes the underlying bytes within roughly 24–48 hours of upload |
|
|
337
356
|
| URL re-fetch | Not required | Fetch via `GET /v3/attachments/{attachmentId}` for a fresh signed URL after TTL expiry |
|
|
338
357
|
| Cross-partner isolation | Enforced | Enforced |
|
|
339
358
|
|
|
@@ -393,9 +412,9 @@ class LinqAPIV3(SyncAPIClient):
|
|
|
393
412
|
|
|
394
413
|
| Data | Persistent tier | Ephemeral tier |
|
|
395
414
|
|---|---|---|
|
|
396
|
-
| Attachment bytes | Retained until you `DELETE` | **Auto-removed
|
|
415
|
+
| Attachment bytes | Retained until you `DELETE` | **Auto-removed within roughly 24–48 hours** of upload, independently of any message window. Also removable via `DELETE` |
|
|
397
416
|
| Attachment metadata (id, filename, mime type, size) | Retained until you `DELETE` | Removed alongside the bytes |
|
|
398
|
-
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message and
|
|
417
|
+
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message's text, formatting, and attachment references are no longer retrievable through the API after that account's configured retention window (60 minutes – 24 hours, default 24 hours) from creation. Metadata is retained; see the Messages page for details |
|
|
399
418
|
| Audit log of deletions | Retained per platform retention policy | Retained per platform retention policy |
|
|
400
419
|
|
|
401
420
|
**In transit:** TLS 1.2+ everywhere. **At rest:** AES-256 (server-side encryption).
|
|
@@ -407,7 +426,7 @@ class LinqAPIV3(SyncAPIClient):
|
|
|
407
426
|
- Allowlist exactly one outbound domain: `cdn.linqapp.com`.
|
|
408
427
|
- Decide whether you need ephemeral attachments (high-sensitivity content) — request enablement through your Linq support contact.
|
|
409
428
|
- Implement `DELETE /v3/attachments/{attachmentId}` calls in your deletion workflow.
|
|
410
|
-
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges
|
|
429
|
+
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges within roughly 24–48 hours of upload.
|
|
411
430
|
- For audit: every deletion is logged on Linq's side. Surface a confirmation in your application UI based on the `204` response.
|
|
412
431
|
- For end-user "right to delete" requests: enumerate attachment ids and `DELETE` each. The platform does not provide a partner-wide wipe endpoint — deletion is per-attachment by design.
|
|
413
432
|
"""
|
|
@@ -1302,35 +1321,39 @@ class AsyncLinqAPIV3(AsyncAPIClient):
|
|
|
1302
1321
|
|
|
1303
1322
|
## Ephemeral Messages (Privacy Tier)
|
|
1304
1323
|
|
|
1305
|
-
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is
|
|
1324
|
+
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is given a **retention window configured for your account**. After that window, the message's text, formatting, and attachment references are no longer retrievable through the API — see the Attachments row below for how the attachment media itself is handled. Metadata about the message is retained: message identifiers, timestamps, phone numbers, and delivery state. Metadata retention is not bounded by this window. Bounded operational copies, such as backups and delivery queues, expire on their own separate schedules. There is no per-message flag; ephemerality is applied automatically based on your configuration.
|
|
1325
|
+
|
|
1326
|
+
The window can be set anywhere from **60 minutes to 24 hours**, and defaults to **24 hours**. Ask your Linq support contact to configure a shorter window; it cannot be changed through the API.
|
|
1306
1327
|
|
|
1307
1328
|
You can request it at two scopes:
|
|
1308
1329
|
|
|
1309
1330
|
| Scope | Effect |
|
|
1310
1331
|
|---|---|
|
|
1311
|
-
| **Partner-wide** | Every outbound and inbound message on every phone number under your account
|
|
1312
|
-
| **Per phone number** | Only the specified phone numbers have
|
|
1332
|
+
| **Partner-wide** | Every outbound and inbound message on every phone number under your account has its content removed from the API surface after your configured window. Metadata is retained. |
|
|
1333
|
+
| **Per phone number** | Only the specified phone numbers have message content removed from the API surface this way. The rest follow the standard message-retention policy. |
|
|
1313
1334
|
|
|
1314
1335
|
**Behavioral differences vs the standard default:**
|
|
1315
1336
|
|
|
1316
1337
|
| Aspect | Standard | Ephemeral |
|
|
1317
1338
|
|---|---|---|
|
|
1318
|
-
| Retention | Retained per the standard message-retention policy | **Hard backstop: 24 hours
|
|
1319
|
-
| After expiry | Message stays retrievable | Message is
|
|
1320
|
-
| Content on expiry | N/A | Text, formatting, and attachment references are
|
|
1339
|
+
| Retention | Retained per the standard message-retention policy | **Hard backstop: your configured window** (60 minutes – 24 hours, default 24 hours) from when the message is created |
|
|
1340
|
+
| After expiry | Message stays retrievable | Message content is no longer retrievable — `GET /v3/messages/{messageId}` returns `404` and it no longer appears in `GET /v3/chats/{chatId}/messages` |
|
|
1341
|
+
| Content on expiry | N/A | Text, formatting, and attachment references are removed from the API surface, not blanked out in place. Metadata (identifiers, timestamps, phone numbers, delivery state) is retained; its retention is not bounded by this window |
|
|
1342
|
+
| Attachments | Retained | Media sent on the **ephemeral attachments tier** is removed on its own storage backstop — within roughly 24–48 hours of upload — independently of the message window, so it can outlast a window shorter than a day. Attachments on the persistent tier (including pre-uploads via `POST /v3/attachments`) are kept until you `DELETE` them |
|
|
1321
1343
|
| Cross-partner isolation | Enforced | Enforced |
|
|
1322
1344
|
|
|
1323
|
-
**How the
|
|
1345
|
+
**How the retention window works:**
|
|
1324
1346
|
|
|
1325
|
-
- The window
|
|
1326
|
-
-
|
|
1347
|
+
- The window runs from **message creation** (`created_at`). It is configured for your account (60 minutes – 24 hours, default 24 hours) and cannot be set per message.
|
|
1348
|
+
- Attachment media follows its own storage backstop rather than the message window — see the Attachments row above.
|
|
1327
1349
|
- Expiry is delivery-independent — the clock starts when the message is created, not when it is delivered or read.
|
|
1350
|
+
- **Deletion happens shortly *after* the window, not exactly at it.** A background sweep runs every ~5 minutes, so a message typically stops being retrievable within about 5 minutes of its expiry, and longer while a backlog is being worked through. Treat the window as the guaranteed *minimum* retention, never as an exact deletion time or an upper bound.
|
|
1328
1351
|
|
|
1329
1352
|
**What you observe:**
|
|
1330
1353
|
|
|
1331
|
-
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time.
|
|
1354
|
+
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time, and they do not report your configured window either — so if you are on a window shorter than 24 hours you cannot derive a message's expiry from the API today. Track the window you agreed with your Linq support contact and compute `created_at + window` yourself.
|
|
1332
1355
|
- **No deletion webhook is sent.** There is no `message.deleted` event — a message simply stops being retrievable once its window passes.
|
|
1333
|
-
- **The backstop
|
|
1356
|
+
- **The attachment backstop is separate from the message window.** API retrievability (the `404` behavior above) ends at your configured window. Ephemeral-tier media objects are removed on their own storage backstop — within roughly 24–48 hours of upload — which is independent of the message window and can outlast a window shorter than a day. Removal of the corresponding entries from the sending device happens asynchronously and can complete after the backstop.
|
|
1334
1357
|
- **Delivery is unaffected.** Ephemeral messages send, deliver, and fire the usual `message.sent` / `message.received` and status webhooks exactly like standard messages. Only retention changes.
|
|
1335
1358
|
|
|
1336
1359
|
**When to choose ephemeral:**
|
|
@@ -1339,7 +1362,7 @@ class AsyncLinqAPIV3(AsyncAPIClient):
|
|
|
1339
1362
|
- The conversation is high-sensitivity (PHI, financial, identity verification) and you do not want it sitting in storage long-term.
|
|
1340
1363
|
- Your application is the system of record — you capture what you need from the delivery webhook in real time and do not rely on reading message history back from Linq later.
|
|
1341
1364
|
|
|
1342
|
-
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message
|
|
1365
|
+
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message once its window passes, persist anything you need to keep from the webhook payload at the time it is delivered.
|
|
1343
1366
|
"""
|
|
1344
1367
|
from .resources.messages import AsyncMessagesResource
|
|
1345
1368
|
|
|
@@ -1373,13 +1396,28 @@ class AsyncLinqAPIV3(AsyncAPIClient):
|
|
|
1373
1396
|
- **Reduce message send latency** — the file is already stored, so sending is faster
|
|
1374
1397
|
|
|
1375
1398
|
**How it works:**
|
|
1376
|
-
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a
|
|
1399
|
+
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a reusable `attachment_id`
|
|
1377
1400
|
2. PUT the raw file bytes to the `upload_url` with the `required_headers` (no JSON or multipart — just the binary content)
|
|
1378
|
-
3. Reference the `attachment_id` in your media part when sending messages (
|
|
1401
|
+
3. Reference the `attachment_id` in your media part when sending messages (stays valid unless deleted — see [Attachment Lifetime](#attachment-lifetime))
|
|
1379
1402
|
|
|
1380
1403
|
**Key difference:** When you provide an external `url`, we download and process the file on every send.
|
|
1381
1404
|
When you use a pre-uploaded `attachment_id`, the file is already stored — so repeated sends skip the download step entirely.
|
|
1382
1405
|
|
|
1406
|
+
## Attachment Lifetime
|
|
1407
|
+
|
|
1408
|
+
An `attachment_id` and its CDN URL stay valid until the file is deleted. Three things delete it:
|
|
1409
|
+
|
|
1410
|
+
| Trigger | Applies to |
|
|
1411
|
+
|---|---|
|
|
1412
|
+
| `DELETE /v3/attachments/{attachmentId}` | Any attachment you own |
|
|
1413
|
+
| Ephemeral **attachments** tier (24–48h storage backstop) | Attachments on ephemeral-tier partners or phone numbers |
|
|
1414
|
+
| Ephemeral **messages** tier | Does **not** remove attachment bytes on its own: ephemeral-tier objects are removed by the 24–48h storage backstop above, and persistent-tier attachments are kept until you `DELETE` them explicitly. |
|
|
1415
|
+
|
|
1416
|
+
Deletion is not reversible, and there is no `attachment.deleted` webhook. On either
|
|
1417
|
+
ephemeral tier, download anything you need to keep when you receive it rather than
|
|
1418
|
+
re-fetching later, and do not assume a pre-uploaded `attachment_id` can be reused
|
|
1419
|
+
indefinitely.
|
|
1420
|
+
|
|
1383
1421
|
## Domain Allowlisting
|
|
1384
1422
|
|
|
1385
1423
|
Attachment URLs in API responses are served from `cdn.linqapp.com`. This includes:
|
|
@@ -1430,7 +1468,7 @@ class AsyncLinqAPIV3(AsyncAPIClient):
|
|
|
1430
1468
|
|
|
1431
1469
|
| Tier | URL pattern | TTL |
|
|
1432
1470
|
|---|---|---|
|
|
1433
|
-
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived |
|
|
1471
|
+
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived — the URL itself does not expire, but see [Attachment Lifetime](#attachment-lifetime) |
|
|
1434
1472
|
| Ephemeral | Pre-signed URL pointing at the ephemeral prefix on `cdn.linqapp.com` | 15 minutes per signed URL — re-fetch via the API for a fresh URL |
|
|
1435
1473
|
|
|
1436
1474
|
Inbound media you receive over webhooks uses the same layout your outbound sends produce, so the URL you store and the URL you build look identical — no special casing in your client.
|
|
@@ -1449,7 +1487,7 @@ class AsyncLinqAPIV3(AsyncAPIClient):
|
|
|
1449
1487
|
| Aspect | Persistent | Ephemeral |
|
|
1450
1488
|
|---|---|---|
|
|
1451
1489
|
| Download URL form | Long-lived CDN URL | Pre-signed URL with short TTL |
|
|
1452
|
-
| Retention floor |
|
|
1490
|
+
| Retention floor | Until you call `DELETE` | **Hard backstop: 24–48h** — even without an explicit `DELETE`, the platform removes the underlying bytes within roughly 24–48 hours of upload |
|
|
1453
1491
|
| URL re-fetch | Not required | Fetch via `GET /v3/attachments/{attachmentId}` for a fresh signed URL after TTL expiry |
|
|
1454
1492
|
| Cross-partner isolation | Enforced | Enforced |
|
|
1455
1493
|
|
|
@@ -1509,9 +1547,9 @@ class AsyncLinqAPIV3(AsyncAPIClient):
|
|
|
1509
1547
|
|
|
1510
1548
|
| Data | Persistent tier | Ephemeral tier |
|
|
1511
1549
|
|---|---|---|
|
|
1512
|
-
| Attachment bytes | Retained until you `DELETE` | **Auto-removed
|
|
1550
|
+
| Attachment bytes | Retained until you `DELETE` | **Auto-removed within roughly 24–48 hours** of upload, independently of any message window. Also removable via `DELETE` |
|
|
1513
1551
|
| Attachment metadata (id, filename, mime type, size) | Retained until you `DELETE` | Removed alongside the bytes |
|
|
1514
|
-
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message and
|
|
1552
|
+
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message's text, formatting, and attachment references are no longer retrievable through the API after that account's configured retention window (60 minutes – 24 hours, default 24 hours) from creation. Metadata is retained; see the Messages page for details |
|
|
1515
1553
|
| Audit log of deletions | Retained per platform retention policy | Retained per platform retention policy |
|
|
1516
1554
|
|
|
1517
1555
|
**In transit:** TLS 1.2+ everywhere. **At rest:** AES-256 (server-side encryption).
|
|
@@ -1523,7 +1561,7 @@ class AsyncLinqAPIV3(AsyncAPIClient):
|
|
|
1523
1561
|
- Allowlist exactly one outbound domain: `cdn.linqapp.com`.
|
|
1524
1562
|
- Decide whether you need ephemeral attachments (high-sensitivity content) — request enablement through your Linq support contact.
|
|
1525
1563
|
- Implement `DELETE /v3/attachments/{attachmentId}` calls in your deletion workflow.
|
|
1526
|
-
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges
|
|
1564
|
+
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges within roughly 24–48 hours of upload.
|
|
1527
1565
|
- For audit: every deletion is logged on Linq's side. Surface a confirmation in your application UI based on the `204` response.
|
|
1528
1566
|
- For end-user "right to delete" requests: enumerate attachment ids and `DELETE` each. The platform does not provide a partner-wide wipe endpoint — deletion is per-attachment by design.
|
|
1529
1567
|
"""
|
|
@@ -2352,35 +2390,39 @@ class LinqAPIV3WithRawResponse:
|
|
|
2352
2390
|
|
|
2353
2391
|
## Ephemeral Messages (Privacy Tier)
|
|
2354
2392
|
|
|
2355
|
-
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is
|
|
2393
|
+
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is given a **retention window configured for your account**. After that window, the message's text, formatting, and attachment references are no longer retrievable through the API — see the Attachments row below for how the attachment media itself is handled. Metadata about the message is retained: message identifiers, timestamps, phone numbers, and delivery state. Metadata retention is not bounded by this window. Bounded operational copies, such as backups and delivery queues, expire on their own separate schedules. There is no per-message flag; ephemerality is applied automatically based on your configuration.
|
|
2394
|
+
|
|
2395
|
+
The window can be set anywhere from **60 minutes to 24 hours**, and defaults to **24 hours**. Ask your Linq support contact to configure a shorter window; it cannot be changed through the API.
|
|
2356
2396
|
|
|
2357
2397
|
You can request it at two scopes:
|
|
2358
2398
|
|
|
2359
2399
|
| Scope | Effect |
|
|
2360
2400
|
|---|---|
|
|
2361
|
-
| **Partner-wide** | Every outbound and inbound message on every phone number under your account
|
|
2362
|
-
| **Per phone number** | Only the specified phone numbers have
|
|
2401
|
+
| **Partner-wide** | Every outbound and inbound message on every phone number under your account has its content removed from the API surface after your configured window. Metadata is retained. |
|
|
2402
|
+
| **Per phone number** | Only the specified phone numbers have message content removed from the API surface this way. The rest follow the standard message-retention policy. |
|
|
2363
2403
|
|
|
2364
2404
|
**Behavioral differences vs the standard default:**
|
|
2365
2405
|
|
|
2366
2406
|
| Aspect | Standard | Ephemeral |
|
|
2367
2407
|
|---|---|---|
|
|
2368
|
-
| Retention | Retained per the standard message-retention policy | **Hard backstop: 24 hours
|
|
2369
|
-
| After expiry | Message stays retrievable | Message is
|
|
2370
|
-
| Content on expiry | N/A | Text, formatting, and attachment references are
|
|
2408
|
+
| Retention | Retained per the standard message-retention policy | **Hard backstop: your configured window** (60 minutes – 24 hours, default 24 hours) from when the message is created |
|
|
2409
|
+
| After expiry | Message stays retrievable | Message content is no longer retrievable — `GET /v3/messages/{messageId}` returns `404` and it no longer appears in `GET /v3/chats/{chatId}/messages` |
|
|
2410
|
+
| Content on expiry | N/A | Text, formatting, and attachment references are removed from the API surface, not blanked out in place. Metadata (identifiers, timestamps, phone numbers, delivery state) is retained; its retention is not bounded by this window |
|
|
2411
|
+
| Attachments | Retained | Media sent on the **ephemeral attachments tier** is removed on its own storage backstop — within roughly 24–48 hours of upload — independently of the message window, so it can outlast a window shorter than a day. Attachments on the persistent tier (including pre-uploads via `POST /v3/attachments`) are kept until you `DELETE` them |
|
|
2371
2412
|
| Cross-partner isolation | Enforced | Enforced |
|
|
2372
2413
|
|
|
2373
|
-
**How the
|
|
2414
|
+
**How the retention window works:**
|
|
2374
2415
|
|
|
2375
|
-
- The window
|
|
2376
|
-
-
|
|
2416
|
+
- The window runs from **message creation** (`created_at`). It is configured for your account (60 minutes – 24 hours, default 24 hours) and cannot be set per message.
|
|
2417
|
+
- Attachment media follows its own storage backstop rather than the message window — see the Attachments row above.
|
|
2377
2418
|
- Expiry is delivery-independent — the clock starts when the message is created, not when it is delivered or read.
|
|
2419
|
+
- **Deletion happens shortly *after* the window, not exactly at it.** A background sweep runs every ~5 minutes, so a message typically stops being retrievable within about 5 minutes of its expiry, and longer while a backlog is being worked through. Treat the window as the guaranteed *minimum* retention, never as an exact deletion time or an upper bound.
|
|
2378
2420
|
|
|
2379
2421
|
**What you observe:**
|
|
2380
2422
|
|
|
2381
|
-
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time.
|
|
2423
|
+
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time, and they do not report your configured window either — so if you are on a window shorter than 24 hours you cannot derive a message's expiry from the API today. Track the window you agreed with your Linq support contact and compute `created_at + window` yourself.
|
|
2382
2424
|
- **No deletion webhook is sent.** There is no `message.deleted` event — a message simply stops being retrievable once its window passes.
|
|
2383
|
-
- **The backstop
|
|
2425
|
+
- **The attachment backstop is separate from the message window.** API retrievability (the `404` behavior above) ends at your configured window. Ephemeral-tier media objects are removed on their own storage backstop — within roughly 24–48 hours of upload — which is independent of the message window and can outlast a window shorter than a day. Removal of the corresponding entries from the sending device happens asynchronously and can complete after the backstop.
|
|
2384
2426
|
- **Delivery is unaffected.** Ephemeral messages send, deliver, and fire the usual `message.sent` / `message.received` and status webhooks exactly like standard messages. Only retention changes.
|
|
2385
2427
|
|
|
2386
2428
|
**When to choose ephemeral:**
|
|
@@ -2389,7 +2431,7 @@ class LinqAPIV3WithRawResponse:
|
|
|
2389
2431
|
- The conversation is high-sensitivity (PHI, financial, identity verification) and you do not want it sitting in storage long-term.
|
|
2390
2432
|
- Your application is the system of record — you capture what you need from the delivery webhook in real time and do not rely on reading message history back from Linq later.
|
|
2391
2433
|
|
|
2392
|
-
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message
|
|
2434
|
+
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message once its window passes, persist anything you need to keep from the webhook payload at the time it is delivered.
|
|
2393
2435
|
"""
|
|
2394
2436
|
from .resources.messages import MessagesResourceWithRawResponse
|
|
2395
2437
|
|
|
@@ -2423,13 +2465,28 @@ class LinqAPIV3WithRawResponse:
|
|
|
2423
2465
|
- **Reduce message send latency** — the file is already stored, so sending is faster
|
|
2424
2466
|
|
|
2425
2467
|
**How it works:**
|
|
2426
|
-
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a
|
|
2468
|
+
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a reusable `attachment_id`
|
|
2427
2469
|
2. PUT the raw file bytes to the `upload_url` with the `required_headers` (no JSON or multipart — just the binary content)
|
|
2428
|
-
3. Reference the `attachment_id` in your media part when sending messages (
|
|
2470
|
+
3. Reference the `attachment_id` in your media part when sending messages (stays valid unless deleted — see [Attachment Lifetime](#attachment-lifetime))
|
|
2429
2471
|
|
|
2430
2472
|
**Key difference:** When you provide an external `url`, we download and process the file on every send.
|
|
2431
2473
|
When you use a pre-uploaded `attachment_id`, the file is already stored — so repeated sends skip the download step entirely.
|
|
2432
2474
|
|
|
2475
|
+
## Attachment Lifetime
|
|
2476
|
+
|
|
2477
|
+
An `attachment_id` and its CDN URL stay valid until the file is deleted. Three things delete it:
|
|
2478
|
+
|
|
2479
|
+
| Trigger | Applies to |
|
|
2480
|
+
|---|---|
|
|
2481
|
+
| `DELETE /v3/attachments/{attachmentId}` | Any attachment you own |
|
|
2482
|
+
| Ephemeral **attachments** tier (24–48h storage backstop) | Attachments on ephemeral-tier partners or phone numbers |
|
|
2483
|
+
| Ephemeral **messages** tier | Does **not** remove attachment bytes on its own: ephemeral-tier objects are removed by the 24–48h storage backstop above, and persistent-tier attachments are kept until you `DELETE` them explicitly. |
|
|
2484
|
+
|
|
2485
|
+
Deletion is not reversible, and there is no `attachment.deleted` webhook. On either
|
|
2486
|
+
ephemeral tier, download anything you need to keep when you receive it rather than
|
|
2487
|
+
re-fetching later, and do not assume a pre-uploaded `attachment_id` can be reused
|
|
2488
|
+
indefinitely.
|
|
2489
|
+
|
|
2433
2490
|
## Domain Allowlisting
|
|
2434
2491
|
|
|
2435
2492
|
Attachment URLs in API responses are served from `cdn.linqapp.com`. This includes:
|
|
@@ -2480,7 +2537,7 @@ class LinqAPIV3WithRawResponse:
|
|
|
2480
2537
|
|
|
2481
2538
|
| Tier | URL pattern | TTL |
|
|
2482
2539
|
|---|---|---|
|
|
2483
|
-
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived |
|
|
2540
|
+
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived — the URL itself does not expire, but see [Attachment Lifetime](#attachment-lifetime) |
|
|
2484
2541
|
| Ephemeral | Pre-signed URL pointing at the ephemeral prefix on `cdn.linqapp.com` | 15 minutes per signed URL — re-fetch via the API for a fresh URL |
|
|
2485
2542
|
|
|
2486
2543
|
Inbound media you receive over webhooks uses the same layout your outbound sends produce, so the URL you store and the URL you build look identical — no special casing in your client.
|
|
@@ -2499,7 +2556,7 @@ class LinqAPIV3WithRawResponse:
|
|
|
2499
2556
|
| Aspect | Persistent | Ephemeral |
|
|
2500
2557
|
|---|---|---|
|
|
2501
2558
|
| Download URL form | Long-lived CDN URL | Pre-signed URL with short TTL |
|
|
2502
|
-
| Retention floor |
|
|
2559
|
+
| Retention floor | Until you call `DELETE` | **Hard backstop: 24–48h** — even without an explicit `DELETE`, the platform removes the underlying bytes within roughly 24–48 hours of upload |
|
|
2503
2560
|
| URL re-fetch | Not required | Fetch via `GET /v3/attachments/{attachmentId}` for a fresh signed URL after TTL expiry |
|
|
2504
2561
|
| Cross-partner isolation | Enforced | Enforced |
|
|
2505
2562
|
|
|
@@ -2559,9 +2616,9 @@ class LinqAPIV3WithRawResponse:
|
|
|
2559
2616
|
|
|
2560
2617
|
| Data | Persistent tier | Ephemeral tier |
|
|
2561
2618
|
|---|---|---|
|
|
2562
|
-
| Attachment bytes | Retained until you `DELETE` | **Auto-removed
|
|
2619
|
+
| Attachment bytes | Retained until you `DELETE` | **Auto-removed within roughly 24–48 hours** of upload, independently of any message window. Also removable via `DELETE` |
|
|
2563
2620
|
| Attachment metadata (id, filename, mime type, size) | Retained until you `DELETE` | Removed alongside the bytes |
|
|
2564
|
-
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message and
|
|
2621
|
+
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message's text, formatting, and attachment references are no longer retrievable through the API after that account's configured retention window (60 minutes – 24 hours, default 24 hours) from creation. Metadata is retained; see the Messages page for details |
|
|
2565
2622
|
| Audit log of deletions | Retained per platform retention policy | Retained per platform retention policy |
|
|
2566
2623
|
|
|
2567
2624
|
**In transit:** TLS 1.2+ everywhere. **At rest:** AES-256 (server-side encryption).
|
|
@@ -2573,7 +2630,7 @@ class LinqAPIV3WithRawResponse:
|
|
|
2573
2630
|
- Allowlist exactly one outbound domain: `cdn.linqapp.com`.
|
|
2574
2631
|
- Decide whether you need ephemeral attachments (high-sensitivity content) — request enablement through your Linq support contact.
|
|
2575
2632
|
- Implement `DELETE /v3/attachments/{attachmentId}` calls in your deletion workflow.
|
|
2576
|
-
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges
|
|
2633
|
+
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges within roughly 24–48 hours of upload.
|
|
2577
2634
|
- For audit: every deletion is logged on Linq's side. Surface a confirmation in your application UI based on the `204` response.
|
|
2578
2635
|
- For end-user "right to delete" requests: enumerate attachment ids and `DELETE` each. The platform does not provide a partner-wide wipe endpoint — deletion is per-attachment by design.
|
|
2579
2636
|
"""
|
|
@@ -3274,35 +3331,39 @@ class AsyncLinqAPIV3WithRawResponse:
|
|
|
3274
3331
|
|
|
3275
3332
|
## Ephemeral Messages (Privacy Tier)
|
|
3276
3333
|
|
|
3277
|
-
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is
|
|
3334
|
+
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is given a **retention window configured for your account**. After that window, the message's text, formatting, and attachment references are no longer retrievable through the API — see the Attachments row below for how the attachment media itself is handled. Metadata about the message is retained: message identifiers, timestamps, phone numbers, and delivery state. Metadata retention is not bounded by this window. Bounded operational copies, such as backups and delivery queues, expire on their own separate schedules. There is no per-message flag; ephemerality is applied automatically based on your configuration.
|
|
3335
|
+
|
|
3336
|
+
The window can be set anywhere from **60 minutes to 24 hours**, and defaults to **24 hours**. Ask your Linq support contact to configure a shorter window; it cannot be changed through the API.
|
|
3278
3337
|
|
|
3279
3338
|
You can request it at two scopes:
|
|
3280
3339
|
|
|
3281
3340
|
| Scope | Effect |
|
|
3282
3341
|
|---|---|
|
|
3283
|
-
| **Partner-wide** | Every outbound and inbound message on every phone number under your account
|
|
3284
|
-
| **Per phone number** | Only the specified phone numbers have
|
|
3342
|
+
| **Partner-wide** | Every outbound and inbound message on every phone number under your account has its content removed from the API surface after your configured window. Metadata is retained. |
|
|
3343
|
+
| **Per phone number** | Only the specified phone numbers have message content removed from the API surface this way. The rest follow the standard message-retention policy. |
|
|
3285
3344
|
|
|
3286
3345
|
**Behavioral differences vs the standard default:**
|
|
3287
3346
|
|
|
3288
3347
|
| Aspect | Standard | Ephemeral |
|
|
3289
3348
|
|---|---|---|
|
|
3290
|
-
| Retention | Retained per the standard message-retention policy | **Hard backstop: 24 hours
|
|
3291
|
-
| After expiry | Message stays retrievable | Message is
|
|
3292
|
-
| Content on expiry | N/A | Text, formatting, and attachment references are
|
|
3349
|
+
| Retention | Retained per the standard message-retention policy | **Hard backstop: your configured window** (60 minutes – 24 hours, default 24 hours) from when the message is created |
|
|
3350
|
+
| After expiry | Message stays retrievable | Message content is no longer retrievable — `GET /v3/messages/{messageId}` returns `404` and it no longer appears in `GET /v3/chats/{chatId}/messages` |
|
|
3351
|
+
| Content on expiry | N/A | Text, formatting, and attachment references are removed from the API surface, not blanked out in place. Metadata (identifiers, timestamps, phone numbers, delivery state) is retained; its retention is not bounded by this window |
|
|
3352
|
+
| Attachments | Retained | Media sent on the **ephemeral attachments tier** is removed on its own storage backstop — within roughly 24–48 hours of upload — independently of the message window, so it can outlast a window shorter than a day. Attachments on the persistent tier (including pre-uploads via `POST /v3/attachments`) are kept until you `DELETE` them |
|
|
3293
3353
|
| Cross-partner isolation | Enforced | Enforced |
|
|
3294
3354
|
|
|
3295
|
-
**How the
|
|
3355
|
+
**How the retention window works:**
|
|
3296
3356
|
|
|
3297
|
-
- The window
|
|
3298
|
-
-
|
|
3357
|
+
- The window runs from **message creation** (`created_at`). It is configured for your account (60 minutes – 24 hours, default 24 hours) and cannot be set per message.
|
|
3358
|
+
- Attachment media follows its own storage backstop rather than the message window — see the Attachments row above.
|
|
3299
3359
|
- Expiry is delivery-independent — the clock starts when the message is created, not when it is delivered or read.
|
|
3360
|
+
- **Deletion happens shortly *after* the window, not exactly at it.** A background sweep runs every ~5 minutes, so a message typically stops being retrievable within about 5 minutes of its expiry, and longer while a backlog is being worked through. Treat the window as the guaranteed *minimum* retention, never as an exact deletion time or an upper bound.
|
|
3300
3361
|
|
|
3301
3362
|
**What you observe:**
|
|
3302
3363
|
|
|
3303
|
-
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time.
|
|
3364
|
+
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time, and they do not report your configured window either — so if you are on a window shorter than 24 hours you cannot derive a message's expiry from the API today. Track the window you agreed with your Linq support contact and compute `created_at + window` yourself.
|
|
3304
3365
|
- **No deletion webhook is sent.** There is no `message.deleted` event — a message simply stops being retrievable once its window passes.
|
|
3305
|
-
- **The backstop
|
|
3366
|
+
- **The attachment backstop is separate from the message window.** API retrievability (the `404` behavior above) ends at your configured window. Ephemeral-tier media objects are removed on their own storage backstop — within roughly 24–48 hours of upload — which is independent of the message window and can outlast a window shorter than a day. Removal of the corresponding entries from the sending device happens asynchronously and can complete after the backstop.
|
|
3306
3367
|
- **Delivery is unaffected.** Ephemeral messages send, deliver, and fire the usual `message.sent` / `message.received` and status webhooks exactly like standard messages. Only retention changes.
|
|
3307
3368
|
|
|
3308
3369
|
**When to choose ephemeral:**
|
|
@@ -3311,7 +3372,7 @@ class AsyncLinqAPIV3WithRawResponse:
|
|
|
3311
3372
|
- The conversation is high-sensitivity (PHI, financial, identity verification) and you do not want it sitting in storage long-term.
|
|
3312
3373
|
- Your application is the system of record — you capture what you need from the delivery webhook in real time and do not rely on reading message history back from Linq later.
|
|
3313
3374
|
|
|
3314
|
-
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message
|
|
3375
|
+
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message once its window passes, persist anything you need to keep from the webhook payload at the time it is delivered.
|
|
3315
3376
|
"""
|
|
3316
3377
|
from .resources.messages import AsyncMessagesResourceWithRawResponse
|
|
3317
3378
|
|
|
@@ -3345,13 +3406,28 @@ class AsyncLinqAPIV3WithRawResponse:
|
|
|
3345
3406
|
- **Reduce message send latency** — the file is already stored, so sending is faster
|
|
3346
3407
|
|
|
3347
3408
|
**How it works:**
|
|
3348
|
-
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a
|
|
3409
|
+
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a reusable `attachment_id`
|
|
3349
3410
|
2. PUT the raw file bytes to the `upload_url` with the `required_headers` (no JSON or multipart — just the binary content)
|
|
3350
|
-
3. Reference the `attachment_id` in your media part when sending messages (
|
|
3411
|
+
3. Reference the `attachment_id` in your media part when sending messages (stays valid unless deleted — see [Attachment Lifetime](#attachment-lifetime))
|
|
3351
3412
|
|
|
3352
3413
|
**Key difference:** When you provide an external `url`, we download and process the file on every send.
|
|
3353
3414
|
When you use a pre-uploaded `attachment_id`, the file is already stored — so repeated sends skip the download step entirely.
|
|
3354
3415
|
|
|
3416
|
+
## Attachment Lifetime
|
|
3417
|
+
|
|
3418
|
+
An `attachment_id` and its CDN URL stay valid until the file is deleted. Three things delete it:
|
|
3419
|
+
|
|
3420
|
+
| Trigger | Applies to |
|
|
3421
|
+
|---|---|
|
|
3422
|
+
| `DELETE /v3/attachments/{attachmentId}` | Any attachment you own |
|
|
3423
|
+
| Ephemeral **attachments** tier (24–48h storage backstop) | Attachments on ephemeral-tier partners or phone numbers |
|
|
3424
|
+
| Ephemeral **messages** tier | Does **not** remove attachment bytes on its own: ephemeral-tier objects are removed by the 24–48h storage backstop above, and persistent-tier attachments are kept until you `DELETE` them explicitly. |
|
|
3425
|
+
|
|
3426
|
+
Deletion is not reversible, and there is no `attachment.deleted` webhook. On either
|
|
3427
|
+
ephemeral tier, download anything you need to keep when you receive it rather than
|
|
3428
|
+
re-fetching later, and do not assume a pre-uploaded `attachment_id` can be reused
|
|
3429
|
+
indefinitely.
|
|
3430
|
+
|
|
3355
3431
|
## Domain Allowlisting
|
|
3356
3432
|
|
|
3357
3433
|
Attachment URLs in API responses are served from `cdn.linqapp.com`. This includes:
|
|
@@ -3402,7 +3478,7 @@ class AsyncLinqAPIV3WithRawResponse:
|
|
|
3402
3478
|
|
|
3403
3479
|
| Tier | URL pattern | TTL |
|
|
3404
3480
|
|---|---|---|
|
|
3405
|
-
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived |
|
|
3481
|
+
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived — the URL itself does not expire, but see [Attachment Lifetime](#attachment-lifetime) |
|
|
3406
3482
|
| Ephemeral | Pre-signed URL pointing at the ephemeral prefix on `cdn.linqapp.com` | 15 minutes per signed URL — re-fetch via the API for a fresh URL |
|
|
3407
3483
|
|
|
3408
3484
|
Inbound media you receive over webhooks uses the same layout your outbound sends produce, so the URL you store and the URL you build look identical — no special casing in your client.
|
|
@@ -3421,7 +3497,7 @@ class AsyncLinqAPIV3WithRawResponse:
|
|
|
3421
3497
|
| Aspect | Persistent | Ephemeral |
|
|
3422
3498
|
|---|---|---|
|
|
3423
3499
|
| Download URL form | Long-lived CDN URL | Pre-signed URL with short TTL |
|
|
3424
|
-
| Retention floor |
|
|
3500
|
+
| Retention floor | Until you call `DELETE` | **Hard backstop: 24–48h** — even without an explicit `DELETE`, the platform removes the underlying bytes within roughly 24–48 hours of upload |
|
|
3425
3501
|
| URL re-fetch | Not required | Fetch via `GET /v3/attachments/{attachmentId}` for a fresh signed URL after TTL expiry |
|
|
3426
3502
|
| Cross-partner isolation | Enforced | Enforced |
|
|
3427
3503
|
|
|
@@ -3481,9 +3557,9 @@ class AsyncLinqAPIV3WithRawResponse:
|
|
|
3481
3557
|
|
|
3482
3558
|
| Data | Persistent tier | Ephemeral tier |
|
|
3483
3559
|
|---|---|---|
|
|
3484
|
-
| Attachment bytes | Retained until you `DELETE` | **Auto-removed
|
|
3560
|
+
| Attachment bytes | Retained until you `DELETE` | **Auto-removed within roughly 24–48 hours** of upload, independently of any message window. Also removable via `DELETE` |
|
|
3485
3561
|
| Attachment metadata (id, filename, mime type, size) | Retained until you `DELETE` | Removed alongside the bytes |
|
|
3486
|
-
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message and
|
|
3562
|
+
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message's text, formatting, and attachment references are no longer retrievable through the API after that account's configured retention window (60 minutes – 24 hours, default 24 hours) from creation. Metadata is retained; see the Messages page for details |
|
|
3487
3563
|
| Audit log of deletions | Retained per platform retention policy | Retained per platform retention policy |
|
|
3488
3564
|
|
|
3489
3565
|
**In transit:** TLS 1.2+ everywhere. **At rest:** AES-256 (server-side encryption).
|
|
@@ -3495,7 +3571,7 @@ class AsyncLinqAPIV3WithRawResponse:
|
|
|
3495
3571
|
- Allowlist exactly one outbound domain: `cdn.linqapp.com`.
|
|
3496
3572
|
- Decide whether you need ephemeral attachments (high-sensitivity content) — request enablement through your Linq support contact.
|
|
3497
3573
|
- Implement `DELETE /v3/attachments/{attachmentId}` calls in your deletion workflow.
|
|
3498
|
-
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges
|
|
3574
|
+
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges within roughly 24–48 hours of upload.
|
|
3499
3575
|
- For audit: every deletion is logged on Linq's side. Surface a confirmation in your application UI based on the `204` response.
|
|
3500
3576
|
- For end-user "right to delete" requests: enumerate attachment ids and `DELETE` each. The platform does not provide a partner-wide wipe endpoint — deletion is per-attachment by design.
|
|
3501
3577
|
"""
|
|
@@ -4196,35 +4272,39 @@ class LinqAPIV3WithStreamedResponse:
|
|
|
4196
4272
|
|
|
4197
4273
|
## Ephemeral Messages (Privacy Tier)
|
|
4198
4274
|
|
|
4199
|
-
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is
|
|
4275
|
+
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is given a **retention window configured for your account**. After that window, the message's text, formatting, and attachment references are no longer retrievable through the API — see the Attachments row below for how the attachment media itself is handled. Metadata about the message is retained: message identifiers, timestamps, phone numbers, and delivery state. Metadata retention is not bounded by this window. Bounded operational copies, such as backups and delivery queues, expire on their own separate schedules. There is no per-message flag; ephemerality is applied automatically based on your configuration.
|
|
4276
|
+
|
|
4277
|
+
The window can be set anywhere from **60 minutes to 24 hours**, and defaults to **24 hours**. Ask your Linq support contact to configure a shorter window; it cannot be changed through the API.
|
|
4200
4278
|
|
|
4201
4279
|
You can request it at two scopes:
|
|
4202
4280
|
|
|
4203
4281
|
| Scope | Effect |
|
|
4204
4282
|
|---|---|
|
|
4205
|
-
| **Partner-wide** | Every outbound and inbound message on every phone number under your account
|
|
4206
|
-
| **Per phone number** | Only the specified phone numbers have
|
|
4283
|
+
| **Partner-wide** | Every outbound and inbound message on every phone number under your account has its content removed from the API surface after your configured window. Metadata is retained. |
|
|
4284
|
+
| **Per phone number** | Only the specified phone numbers have message content removed from the API surface this way. The rest follow the standard message-retention policy. |
|
|
4207
4285
|
|
|
4208
4286
|
**Behavioral differences vs the standard default:**
|
|
4209
4287
|
|
|
4210
4288
|
| Aspect | Standard | Ephemeral |
|
|
4211
4289
|
|---|---|---|
|
|
4212
|
-
| Retention | Retained per the standard message-retention policy | **Hard backstop: 24 hours
|
|
4213
|
-
| After expiry | Message stays retrievable | Message is
|
|
4214
|
-
| Content on expiry | N/A | Text, formatting, and attachment references are
|
|
4290
|
+
| Retention | Retained per the standard message-retention policy | **Hard backstop: your configured window** (60 minutes – 24 hours, default 24 hours) from when the message is created |
|
|
4291
|
+
| After expiry | Message stays retrievable | Message content is no longer retrievable — `GET /v3/messages/{messageId}` returns `404` and it no longer appears in `GET /v3/chats/{chatId}/messages` |
|
|
4292
|
+
| Content on expiry | N/A | Text, formatting, and attachment references are removed from the API surface, not blanked out in place. Metadata (identifiers, timestamps, phone numbers, delivery state) is retained; its retention is not bounded by this window |
|
|
4293
|
+
| Attachments | Retained | Media sent on the **ephemeral attachments tier** is removed on its own storage backstop — within roughly 24–48 hours of upload — independently of the message window, so it can outlast a window shorter than a day. Attachments on the persistent tier (including pre-uploads via `POST /v3/attachments`) are kept until you `DELETE` them |
|
|
4215
4294
|
| Cross-partner isolation | Enforced | Enforced |
|
|
4216
4295
|
|
|
4217
|
-
**How the
|
|
4296
|
+
**How the retention window works:**
|
|
4218
4297
|
|
|
4219
|
-
- The window
|
|
4220
|
-
-
|
|
4298
|
+
- The window runs from **message creation** (`created_at`). It is configured for your account (60 minutes – 24 hours, default 24 hours) and cannot be set per message.
|
|
4299
|
+
- Attachment media follows its own storage backstop rather than the message window — see the Attachments row above.
|
|
4221
4300
|
- Expiry is delivery-independent — the clock starts when the message is created, not when it is delivered or read.
|
|
4301
|
+
- **Deletion happens shortly *after* the window, not exactly at it.** A background sweep runs every ~5 minutes, so a message typically stops being retrievable within about 5 minutes of its expiry, and longer while a backlog is being worked through. Treat the window as the guaranteed *minimum* retention, never as an exact deletion time or an upper bound.
|
|
4222
4302
|
|
|
4223
4303
|
**What you observe:**
|
|
4224
4304
|
|
|
4225
|
-
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time.
|
|
4305
|
+
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time, and they do not report your configured window either — so if you are on a window shorter than 24 hours you cannot derive a message's expiry from the API today. Track the window you agreed with your Linq support contact and compute `created_at + window` yourself.
|
|
4226
4306
|
- **No deletion webhook is sent.** There is no `message.deleted` event — a message simply stops being retrievable once its window passes.
|
|
4227
|
-
- **The backstop
|
|
4307
|
+
- **The attachment backstop is separate from the message window.** API retrievability (the `404` behavior above) ends at your configured window. Ephemeral-tier media objects are removed on their own storage backstop — within roughly 24–48 hours of upload — which is independent of the message window and can outlast a window shorter than a day. Removal of the corresponding entries from the sending device happens asynchronously and can complete after the backstop.
|
|
4228
4308
|
- **Delivery is unaffected.** Ephemeral messages send, deliver, and fire the usual `message.sent` / `message.received` and status webhooks exactly like standard messages. Only retention changes.
|
|
4229
4309
|
|
|
4230
4310
|
**When to choose ephemeral:**
|
|
@@ -4233,7 +4313,7 @@ class LinqAPIV3WithStreamedResponse:
|
|
|
4233
4313
|
- The conversation is high-sensitivity (PHI, financial, identity verification) and you do not want it sitting in storage long-term.
|
|
4234
4314
|
- Your application is the system of record — you capture what you need from the delivery webhook in real time and do not rely on reading message history back from Linq later.
|
|
4235
4315
|
|
|
4236
|
-
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message
|
|
4316
|
+
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message once its window passes, persist anything you need to keep from the webhook payload at the time it is delivered.
|
|
4237
4317
|
"""
|
|
4238
4318
|
from .resources.messages import MessagesResourceWithStreamingResponse
|
|
4239
4319
|
|
|
@@ -4267,13 +4347,28 @@ class LinqAPIV3WithStreamedResponse:
|
|
|
4267
4347
|
- **Reduce message send latency** — the file is already stored, so sending is faster
|
|
4268
4348
|
|
|
4269
4349
|
**How it works:**
|
|
4270
|
-
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a
|
|
4350
|
+
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a reusable `attachment_id`
|
|
4271
4351
|
2. PUT the raw file bytes to the `upload_url` with the `required_headers` (no JSON or multipart — just the binary content)
|
|
4272
|
-
3. Reference the `attachment_id` in your media part when sending messages (
|
|
4352
|
+
3. Reference the `attachment_id` in your media part when sending messages (stays valid unless deleted — see [Attachment Lifetime](#attachment-lifetime))
|
|
4273
4353
|
|
|
4274
4354
|
**Key difference:** When you provide an external `url`, we download and process the file on every send.
|
|
4275
4355
|
When you use a pre-uploaded `attachment_id`, the file is already stored — so repeated sends skip the download step entirely.
|
|
4276
4356
|
|
|
4357
|
+
## Attachment Lifetime
|
|
4358
|
+
|
|
4359
|
+
An `attachment_id` and its CDN URL stay valid until the file is deleted. Three things delete it:
|
|
4360
|
+
|
|
4361
|
+
| Trigger | Applies to |
|
|
4362
|
+
|---|---|
|
|
4363
|
+
| `DELETE /v3/attachments/{attachmentId}` | Any attachment you own |
|
|
4364
|
+
| Ephemeral **attachments** tier (24–48h storage backstop) | Attachments on ephemeral-tier partners or phone numbers |
|
|
4365
|
+
| Ephemeral **messages** tier | Does **not** remove attachment bytes on its own: ephemeral-tier objects are removed by the 24–48h storage backstop above, and persistent-tier attachments are kept until you `DELETE` them explicitly. |
|
|
4366
|
+
|
|
4367
|
+
Deletion is not reversible, and there is no `attachment.deleted` webhook. On either
|
|
4368
|
+
ephemeral tier, download anything you need to keep when you receive it rather than
|
|
4369
|
+
re-fetching later, and do not assume a pre-uploaded `attachment_id` can be reused
|
|
4370
|
+
indefinitely.
|
|
4371
|
+
|
|
4277
4372
|
## Domain Allowlisting
|
|
4278
4373
|
|
|
4279
4374
|
Attachment URLs in API responses are served from `cdn.linqapp.com`. This includes:
|
|
@@ -4324,7 +4419,7 @@ class LinqAPIV3WithStreamedResponse:
|
|
|
4324
4419
|
|
|
4325
4420
|
| Tier | URL pattern | TTL |
|
|
4326
4421
|
|---|---|---|
|
|
4327
|
-
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived |
|
|
4422
|
+
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived — the URL itself does not expire, but see [Attachment Lifetime](#attachment-lifetime) |
|
|
4328
4423
|
| Ephemeral | Pre-signed URL pointing at the ephemeral prefix on `cdn.linqapp.com` | 15 minutes per signed URL — re-fetch via the API for a fresh URL |
|
|
4329
4424
|
|
|
4330
4425
|
Inbound media you receive over webhooks uses the same layout your outbound sends produce, so the URL you store and the URL you build look identical — no special casing in your client.
|
|
@@ -4343,7 +4438,7 @@ class LinqAPIV3WithStreamedResponse:
|
|
|
4343
4438
|
| Aspect | Persistent | Ephemeral |
|
|
4344
4439
|
|---|---|---|
|
|
4345
4440
|
| Download URL form | Long-lived CDN URL | Pre-signed URL with short TTL |
|
|
4346
|
-
| Retention floor |
|
|
4441
|
+
| Retention floor | Until you call `DELETE` | **Hard backstop: 24–48h** — even without an explicit `DELETE`, the platform removes the underlying bytes within roughly 24–48 hours of upload |
|
|
4347
4442
|
| URL re-fetch | Not required | Fetch via `GET /v3/attachments/{attachmentId}` for a fresh signed URL after TTL expiry |
|
|
4348
4443
|
| Cross-partner isolation | Enforced | Enforced |
|
|
4349
4444
|
|
|
@@ -4403,9 +4498,9 @@ class LinqAPIV3WithStreamedResponse:
|
|
|
4403
4498
|
|
|
4404
4499
|
| Data | Persistent tier | Ephemeral tier |
|
|
4405
4500
|
|---|---|---|
|
|
4406
|
-
| Attachment bytes | Retained until you `DELETE` | **Auto-removed
|
|
4501
|
+
| Attachment bytes | Retained until you `DELETE` | **Auto-removed within roughly 24–48 hours** of upload, independently of any message window. Also removable via `DELETE` |
|
|
4407
4502
|
| Attachment metadata (id, filename, mime type, size) | Retained until you `DELETE` | Removed alongside the bytes |
|
|
4408
|
-
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message and
|
|
4503
|
+
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message's text, formatting, and attachment references are no longer retrievable through the API after that account's configured retention window (60 minutes – 24 hours, default 24 hours) from creation. Metadata is retained; see the Messages page for details |
|
|
4409
4504
|
| Audit log of deletions | Retained per platform retention policy | Retained per platform retention policy |
|
|
4410
4505
|
|
|
4411
4506
|
**In transit:** TLS 1.2+ everywhere. **At rest:** AES-256 (server-side encryption).
|
|
@@ -4417,7 +4512,7 @@ class LinqAPIV3WithStreamedResponse:
|
|
|
4417
4512
|
- Allowlist exactly one outbound domain: `cdn.linqapp.com`.
|
|
4418
4513
|
- Decide whether you need ephemeral attachments (high-sensitivity content) — request enablement through your Linq support contact.
|
|
4419
4514
|
- Implement `DELETE /v3/attachments/{attachmentId}` calls in your deletion workflow.
|
|
4420
|
-
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges
|
|
4515
|
+
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges within roughly 24–48 hours of upload.
|
|
4421
4516
|
- For audit: every deletion is logged on Linq's side. Surface a confirmation in your application UI based on the `204` response.
|
|
4422
4517
|
- For end-user "right to delete" requests: enumerate attachment ids and `DELETE` each. The platform does not provide a partner-wide wipe endpoint — deletion is per-attachment by design.
|
|
4423
4518
|
"""
|
|
@@ -5118,35 +5213,39 @@ class AsyncLinqAPIV3WithStreamedResponse:
|
|
|
5118
5213
|
|
|
5119
5214
|
## Ephemeral Messages (Privacy Tier)
|
|
5120
5215
|
|
|
5121
|
-
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is
|
|
5216
|
+
For regulated or sensitive conversations, opt in to the **ephemeral messages** tier by contacting your Linq support contact. When enabled, every message on the covered phone numbers is given a **retention window configured for your account**. After that window, the message's text, formatting, and attachment references are no longer retrievable through the API — see the Attachments row below for how the attachment media itself is handled. Metadata about the message is retained: message identifiers, timestamps, phone numbers, and delivery state. Metadata retention is not bounded by this window. Bounded operational copies, such as backups and delivery queues, expire on their own separate schedules. There is no per-message flag; ephemerality is applied automatically based on your configuration.
|
|
5217
|
+
|
|
5218
|
+
The window can be set anywhere from **60 minutes to 24 hours**, and defaults to **24 hours**. Ask your Linq support contact to configure a shorter window; it cannot be changed through the API.
|
|
5122
5219
|
|
|
5123
5220
|
You can request it at two scopes:
|
|
5124
5221
|
|
|
5125
5222
|
| Scope | Effect |
|
|
5126
5223
|
|---|---|
|
|
5127
|
-
| **Partner-wide** | Every outbound and inbound message on every phone number under your account
|
|
5128
|
-
| **Per phone number** | Only the specified phone numbers have
|
|
5224
|
+
| **Partner-wide** | Every outbound and inbound message on every phone number under your account has its content removed from the API surface after your configured window. Metadata is retained. |
|
|
5225
|
+
| **Per phone number** | Only the specified phone numbers have message content removed from the API surface this way. The rest follow the standard message-retention policy. |
|
|
5129
5226
|
|
|
5130
5227
|
**Behavioral differences vs the standard default:**
|
|
5131
5228
|
|
|
5132
5229
|
| Aspect | Standard | Ephemeral |
|
|
5133
5230
|
|---|---|---|
|
|
5134
|
-
| Retention | Retained per the standard message-retention policy | **Hard backstop: 24 hours
|
|
5135
|
-
| After expiry | Message stays retrievable | Message is
|
|
5136
|
-
| Content on expiry | N/A | Text, formatting, and attachment references are
|
|
5231
|
+
| Retention | Retained per the standard message-retention policy | **Hard backstop: your configured window** (60 minutes – 24 hours, default 24 hours) from when the message is created |
|
|
5232
|
+
| After expiry | Message stays retrievable | Message content is no longer retrievable — `GET /v3/messages/{messageId}` returns `404` and it no longer appears in `GET /v3/chats/{chatId}/messages` |
|
|
5233
|
+
| Content on expiry | N/A | Text, formatting, and attachment references are removed from the API surface, not blanked out in place. Metadata (identifiers, timestamps, phone numbers, delivery state) is retained; its retention is not bounded by this window |
|
|
5234
|
+
| Attachments | Retained | Media sent on the **ephemeral attachments tier** is removed on its own storage backstop — within roughly 24–48 hours of upload — independently of the message window, so it can outlast a window shorter than a day. Attachments on the persistent tier (including pre-uploads via `POST /v3/attachments`) are kept until you `DELETE` them |
|
|
5137
5235
|
| Cross-partner isolation | Enforced | Enforced |
|
|
5138
5236
|
|
|
5139
|
-
**How the
|
|
5237
|
+
**How the retention window works:**
|
|
5140
5238
|
|
|
5141
|
-
- The window
|
|
5142
|
-
-
|
|
5239
|
+
- The window runs from **message creation** (`created_at`). It is configured for your account (60 minutes – 24 hours, default 24 hours) and cannot be set per message.
|
|
5240
|
+
- Attachment media follows its own storage backstop rather than the message window — see the Attachments row above.
|
|
5143
5241
|
- Expiry is delivery-independent — the clock starts when the message is created, not when it is delivered or read.
|
|
5242
|
+
- **Deletion happens shortly *after* the window, not exactly at it.** A background sweep runs every ~5 minutes, so a message typically stops being retrievable within about 5 minutes of its expiry, and longer while a backlog is being worked through. Treat the window as the guaranteed *minimum* retention, never as an exact deletion time or an upper bound.
|
|
5144
5243
|
|
|
5145
5244
|
**What you observe:**
|
|
5146
5245
|
|
|
5147
|
-
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time.
|
|
5246
|
+
- **No expiry timestamp is exposed.** API responses and webhook payloads do not include the deletion time, and they do not report your configured window either — so if you are on a window shorter than 24 hours you cannot derive a message's expiry from the API today. Track the window you agreed with your Linq support contact and compute `created_at + window` yourself.
|
|
5148
5247
|
- **No deletion webhook is sent.** There is no `message.deleted` event — a message simply stops being retrievable once its window passes.
|
|
5149
|
-
- **The backstop
|
|
5248
|
+
- **The attachment backstop is separate from the message window.** API retrievability (the `404` behavior above) ends at your configured window. Ephemeral-tier media objects are removed on their own storage backstop — within roughly 24–48 hours of upload — which is independent of the message window and can outlast a window shorter than a day. Removal of the corresponding entries from the sending device happens asynchronously and can complete after the backstop.
|
|
5150
5249
|
- **Delivery is unaffected.** Ephemeral messages send, deliver, and fire the usual `message.sent` / `message.received` and status webhooks exactly like standard messages. Only retention changes.
|
|
5151
5250
|
|
|
5152
5251
|
**When to choose ephemeral:**
|
|
@@ -5155,7 +5254,7 @@ class AsyncLinqAPIV3WithStreamedResponse:
|
|
|
5155
5254
|
- The conversation is high-sensitivity (PHI, financial, identity verification) and you do not want it sitting in storage long-term.
|
|
5156
5255
|
- Your application is the system of record — you capture what you need from the delivery webhook in real time and do not rely on reading message history back from Linq later.
|
|
5157
5256
|
|
|
5158
|
-
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message
|
|
5257
|
+
**Important:** ephemeral applies in *both directions* — messages you send **and** messages received by the phone numbers in that scope. Because Linq can no longer return the message once its window passes, persist anything you need to keep from the webhook payload at the time it is delivered.
|
|
5159
5258
|
"""
|
|
5160
5259
|
from .resources.messages import AsyncMessagesResourceWithStreamingResponse
|
|
5161
5260
|
|
|
@@ -5189,13 +5288,28 @@ class AsyncLinqAPIV3WithStreamedResponse:
|
|
|
5189
5288
|
- **Reduce message send latency** — the file is already stored, so sending is faster
|
|
5190
5289
|
|
|
5191
5290
|
**How it works:**
|
|
5192
|
-
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a
|
|
5291
|
+
1. `POST /v3/attachments` with file metadata → returns a presigned `upload_url` (valid for **15 minutes**) and a reusable `attachment_id`
|
|
5193
5292
|
2. PUT the raw file bytes to the `upload_url` with the `required_headers` (no JSON or multipart — just the binary content)
|
|
5194
|
-
3. Reference the `attachment_id` in your media part when sending messages (
|
|
5293
|
+
3. Reference the `attachment_id` in your media part when sending messages (stays valid unless deleted — see [Attachment Lifetime](#attachment-lifetime))
|
|
5195
5294
|
|
|
5196
5295
|
**Key difference:** When you provide an external `url`, we download and process the file on every send.
|
|
5197
5296
|
When you use a pre-uploaded `attachment_id`, the file is already stored — so repeated sends skip the download step entirely.
|
|
5198
5297
|
|
|
5298
|
+
## Attachment Lifetime
|
|
5299
|
+
|
|
5300
|
+
An `attachment_id` and its CDN URL stay valid until the file is deleted. Three things delete it:
|
|
5301
|
+
|
|
5302
|
+
| Trigger | Applies to |
|
|
5303
|
+
|---|---|
|
|
5304
|
+
| `DELETE /v3/attachments/{attachmentId}` | Any attachment you own |
|
|
5305
|
+
| Ephemeral **attachments** tier (24–48h storage backstop) | Attachments on ephemeral-tier partners or phone numbers |
|
|
5306
|
+
| Ephemeral **messages** tier | Does **not** remove attachment bytes on its own: ephemeral-tier objects are removed by the 24–48h storage backstop above, and persistent-tier attachments are kept until you `DELETE` them explicitly. |
|
|
5307
|
+
|
|
5308
|
+
Deletion is not reversible, and there is no `attachment.deleted` webhook. On either
|
|
5309
|
+
ephemeral tier, download anything you need to keep when you receive it rather than
|
|
5310
|
+
re-fetching later, and do not assume a pre-uploaded `attachment_id` can be reused
|
|
5311
|
+
indefinitely.
|
|
5312
|
+
|
|
5199
5313
|
## Domain Allowlisting
|
|
5200
5314
|
|
|
5201
5315
|
Attachment URLs in API responses are served from `cdn.linqapp.com`. This includes:
|
|
@@ -5246,7 +5360,7 @@ class AsyncLinqAPIV3WithStreamedResponse:
|
|
|
5246
5360
|
|
|
5247
5361
|
| Tier | URL pattern | TTL |
|
|
5248
5362
|
|---|---|---|
|
|
5249
|
-
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived |
|
|
5363
|
+
| Persistent (default) | `https://cdn.linqapp.com/attachments/partners/{partner_id}/{attachment_id}/{filename}` | Long-lived — the URL itself does not expire, but see [Attachment Lifetime](#attachment-lifetime) |
|
|
5250
5364
|
| Ephemeral | Pre-signed URL pointing at the ephemeral prefix on `cdn.linqapp.com` | 15 minutes per signed URL — re-fetch via the API for a fresh URL |
|
|
5251
5365
|
|
|
5252
5366
|
Inbound media you receive over webhooks uses the same layout your outbound sends produce, so the URL you store and the URL you build look identical — no special casing in your client.
|
|
@@ -5265,7 +5379,7 @@ class AsyncLinqAPIV3WithStreamedResponse:
|
|
|
5265
5379
|
| Aspect | Persistent | Ephemeral |
|
|
5266
5380
|
|---|---|---|
|
|
5267
5381
|
| Download URL form | Long-lived CDN URL | Pre-signed URL with short TTL |
|
|
5268
|
-
| Retention floor |
|
|
5382
|
+
| Retention floor | Until you call `DELETE` | **Hard backstop: 24–48h** — even without an explicit `DELETE`, the platform removes the underlying bytes within roughly 24–48 hours of upload |
|
|
5269
5383
|
| URL re-fetch | Not required | Fetch via `GET /v3/attachments/{attachmentId}` for a fresh signed URL after TTL expiry |
|
|
5270
5384
|
| Cross-partner isolation | Enforced | Enforced |
|
|
5271
5385
|
|
|
@@ -5325,9 +5439,9 @@ class AsyncLinqAPIV3WithStreamedResponse:
|
|
|
5325
5439
|
|
|
5326
5440
|
| Data | Persistent tier | Ephemeral tier |
|
|
5327
5441
|
|---|---|---|
|
|
5328
|
-
| Attachment bytes | Retained until you `DELETE` | **Auto-removed
|
|
5442
|
+
| Attachment bytes | Retained until you `DELETE` | **Auto-removed within roughly 24–48 hours** of upload, independently of any message window. Also removable via `DELETE` |
|
|
5329
5443
|
| Attachment metadata (id, filename, mime type, size) | Retained until you `DELETE` | Removed alongside the bytes |
|
|
5330
|
-
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message and
|
|
5444
|
+
| Message body & parts | Retained per message-retention policy | Retained per message-retention policy — unless the line also has **ephemeral messages** enabled (see the Messages page), in which case the message's text, formatting, and attachment references are no longer retrievable through the API after that account's configured retention window (60 minutes – 24 hours, default 24 hours) from creation. Metadata is retained; see the Messages page for details |
|
|
5331
5445
|
| Audit log of deletions | Retained per platform retention policy | Retained per platform retention policy |
|
|
5332
5446
|
|
|
5333
5447
|
**In transit:** TLS 1.2+ everywhere. **At rest:** AES-256 (server-side encryption).
|
|
@@ -5339,7 +5453,7 @@ class AsyncLinqAPIV3WithStreamedResponse:
|
|
|
5339
5453
|
- Allowlist exactly one outbound domain: `cdn.linqapp.com`.
|
|
5340
5454
|
- Decide whether you need ephemeral attachments (high-sensitivity content) — request enablement through your Linq support contact.
|
|
5341
5455
|
- Implement `DELETE /v3/attachments/{attachmentId}` calls in your deletion workflow.
|
|
5342
|
-
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges
|
|
5456
|
+
- Persist any attachments your application needs long-term — Linq is the authoritative source until you delete, but the ephemeral tier auto-purges within roughly 24–48 hours of upload.
|
|
5343
5457
|
- For audit: every deletion is logged on Linq's side. Surface a confirmation in your application UI based on the `204` response.
|
|
5344
5458
|
- For end-user "right to delete" requests: enumerate attachment ids and `DELETE` each. The platform does not provide a partner-wide wipe endpoint — deletion is per-attachment by design.
|
|
5345
5459
|
"""
|