api.drop.m7.org API reference
api.drop.m7.org lets an M7 user or application create an encrypted,
time-limited drop, inspect it, and allow a recipient to retrieve it once. Use
the API to build short-lived payload handoffs for people, command-line tools,
and other applications. A drop can be stored immediately or reserved first
and activated when its payload is ready.
Base URL
https://api.drop.m7.org
Production application
Use Dead Drop to create and inspect owner-scoped drops, retrieve a payload by its drop ID and key, and revoke a drop through the production web application.
Authentication
This service uses a project-specific authorization process that combines an M7 access token with a secret key for payload access. Send JSON requests with the access token unless the route table says the route can be called anonymously:
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
This API does not issue access tokens. Obtain them through M7 SSO and follow the complete authorization and credential guide for token acquisition, principal boundaries, drop-key handling, expiry, revocation, and DPoP status.
| Token principal | Supported use |
|---|---|
| M7 user or OAuth application | Creates and manages only drops owned by that principal. |
admin or root principal |
Uses the same owner boundary except that /v1/drop/delete may delete another principal's drop. |
| Unauthenticated caller | Can call /v1/consume only for a drop whose anonymous value is true; the drop id and key are still required. |
User drop routes normally operate on drops owned by the bearer-token
principal. The privileged exception for /v1/drop/delete is documented with
that route.
Request and response format
Use POST with a JSON object for every documented route. A successful
response has this envelope:
{
"status": 1,
"comment": "OK",
"data": {}
}
status is the application result. Handle the HTTP status independently.
Failures use this envelope:
{
"status": 0,
"code": 400,
"comment": "Error description"
}
For example, a missing or unsuitable principal is rejected with HTTP 401 or
403; a missing drop is 404; lifecycle conflicts are 409; and an expired
payload read is 410.
IDs, keys, and times
id and key are 64-character hexadecimal strings. New integrations should
treat a generated key as secret material: it is returned only when a drop is
stored or activated, and is required to retrieve or consume the encrypted
payload. Store it securely; the API cannot recover it later.
All returned timestamps, including created_at and expires_at, are UTC
timestamp strings. To choose an expiration time, send a future Unix timestamp
or a future date-time string in expires_at. expires is an accepted alias,
but new integrations should use expires_at.
Drop object
Summary responses and list items contain the fields below. A keyed read or consume also includes the payload fields described afterward.
| Field | Type | Description |
|---|---|---|
id |
String | Drop identifier. |
owner |
String or null |
Owner principal identifier. |
anonymous |
Boolean | Whether /v1/consume may be called without an owner token. |
kind |
String or null |
Caller-defined drop category. |
status |
String | reserved, active, consumed, revoked, or calculated expired. |
is_expired |
Boolean | Whether expires_at has passed. |
payload_format |
String | json, text, html, or base64. |
content_type |
String or null |
Payload media type. |
metadata |
JSON value or null |
Caller-supplied metadata. |
created_at |
String | Creation time in UTC. |
modified_at |
String | Last modification time in UTC. |
accessed_at |
String or null |
Last successful keyed read or consume time in UTC. |
expires_at |
String | Expiration time in UTC. |
Keyed payload responses additionally contain:
| Field | Type | Description |
|---|---|---|
payload |
JSON value or String | Decrypted payload. Its type follows payload_format. |
consumed |
Boolean | true when this response consumed the drop. |
cleared |
Boolean | true when the payload was cleared as part of this response. |
Lifecycle
reserve -> reserved -> activate -> active -> consume -> consumed
| |
+-> revoke -------+-> revoked
active or reserved past expires_at -> expired
/v1/drop/store creates an active drop directly. A consumed or revoked
drop has its stored payload cleared. An expired, consumed, or revoked drop
cannot be activated or consumed.
Pagination
The list routes return a pagination object in data. They accept the
following fields:
| Field | Required | Behavior |
|---|---|---|
limit |
No | Default 20; values below 1 use the default; valid values are capped at 100. |
cursor |
No | Cursor in the form `created_at |
offset |
No | Zero-based offset, used when no non-empty cursor is supplied. |
page_number |
No | One-based page number, used when neither cursor nor offset is supplied. |
cursor must have exactly two parts separated by |; its id part must be a
64-character hexadecimal identifier. offset must be an integer greater than
or equal to 0, and page_number must be an integer greater than or equal to
1.
{
"status": 1,
"comment": "OK",
"data": {
"items": [],
"limit": 20,
"total_count": 0,
"next_offset": 20,
"page_number": 1,
"page_total": 0,
"next_cursor": null
}
}
next_cursor is null when there is no following page. Use it as the next
request's cursor when it is present.
Guides
- Authorization — tokens, principals, ownership, drop keys, credential lifecycle, and errors.
- Drop lifecycle — create, inspect, retrieve, list, revoke, and delete drops.