DropplinkDocsPowered bydropp.

Server API

Server-to-server API

Revenue, refunds and data deletion from your backend, with your server key.

POST   https://attribution.ondropp.app/v1/s2s/events
DELETE https://attribution.ondropp.app/v1/s2s/users/:userId
GET    https://attribution.ondropp.app/v1/s2s/deletions/:requestId
Authorization: Bearer sk_5a7c9e1b3d2f4a60.<secret>
Content-Type: application/json

For your backend: payment webhooks, renewals, refunds and website orders. Authenticate with the app's server key as a bearer token. There's nothing to sign. For a walkthrough, see Send revenue from your server.

StatuscodeMeaning
401missing_tokenNo Authorization: Bearer … header.
401invalid_keyUnknown, revoked or wrong key. An SDK key is refused here too.
429rate_limitedOver 500 requests a second for this key. Wait Retry-After seconds, then retry.

Send events#

POST /v1/s2s/events, up to 100 events per request.

Request body
{
  "events": [
    { "eventId": "order-A1099", "userId": "user_8812", "name": "subscription_renewed", "ts": 1760700300,
      "revenue": { "amount": 199, "currency": "INR", "orderId": "A1099" } },
    { "eventId": "refund-A1023", "userId": "user_8812", "name": "refund", "ts": 1760700400,
      "revenue": { "amount": -499, "currency": "INR", "orderId": "A1023" } }
  ]
}
FieldRules
eventIdYour own stable ID, like an order or payment ID: 1–128 printable characters. The same ID within 8 days is stored once.
userId / installId / visitorId / clickIdAt least one. userId is the ID your app passes to identify. visitorId is the web script's visitor ID (the dropp_vid cookie, or dropplink.getVisitorId()). clickId is the dropp_click_id a website visit arrived with, for sites without the script (Web).
namesnake_case, as for app events.
tsWhen it happened, unix seconds, within the last 7 days.
propsOptional, same rules as app events. No personal data.
revenueamount with at most 2 decimals, negative for a refund (with the refunded order's orderId). currency is an ISO 4217 code.
200 OK
{ "accepted": 1, "duplicates": 0, "pending": 1, "rejected": [], "warnings": [] }
FieldMeaning
acceptedStored now.
duplicatesAlready stored by an earlier request with the same eventId.
pendingStored, waiting for your app to identify this user (see below).
rejectedNever accepted: invalid_event, too_old, too_far_in_future, or unknown_install for an installId Dropplink hasn't seen.
warningsStored, with a caveat: pii_in_props lists the properties removed because they looked like personal data; unknown_click means the clickId credited nothing (no such click for this app, a link-preview bot's, more than 30 days before the event, or after it); unknown_visitor means no website visitor with that visitorId for this app (the event is stored organic, or waits for its userId).

Which creator gets it:

  1. A userId your app has identified: that user's creator. See Users and revenue credit.
  2. Only an installId: that install's attribution, or its user's creator if it's logged in.
  3. A visitorId or a clickId, when 1 and 2 give no creator: the visitor's first Dropplink click (or that click), so first touch still wins. Stored with the platform web when no install is named. With a userId too, the click becomes that user's first touch, so their later orders are credited by userId alone, on any device; a visitorId also marks that visitor as this user (verified). See Web.
  4. A userId your app hasn't identified yet: pending. It's credited as soon as the user is identified, or stored as organic after 7 days. It's never dropped.

Revenue is stored in its own currency and also converted to rupees at that day's rate.

503 storage_unavailable means nothing from the request was kept: send it again after Retry-After seconds. Because eventId is yours, resending is always safe.

Delete a user's data#

DELETE /v1/s2s/users/:userId, for account deletion and data requests (DPDP, GDPR). URL-encode the user ID.

202 Accepted
{ "requestId": "6711a0c2f1e4b8a9c3d2e3a0", "status": "pending", "requestedAt": "2026-10-22T10:00:00.000Z", "completedAt": null, "counts": null }

Dropplink deletes the user's identity, events and pending events, and the website visitors linked to them with their visits and page views, and removes the user and device details from their installs. Installs keep their attribution as anonymous counts, so creator totals don't change. It usually finishes within seconds; a failed run is retried automatically, and it always completes within 72 hours.

Check a deletion#

GET /v1/s2s/deletions/:requestId

200 OK
{ "requestId": "6711a0c2f1e4b8a9c3d2e3a0", "status": "done", "requestedAt": "…", "completedAt": "…",
  "counts": { "identities": 1, "events": 14, "pendingEvents": 0, "installs": 2, "webVisitors": 1 } }

status is pending, done or failed (failed runs are retried). You can only see your own app's requests; others return 404 deletion_not_found. The record keeps a hash of the user ID, never the ID itself.

Something unclear? Tell us.Powered bydropp.