adjust-icon

TrueLink API (Deep Link Generator API)

Use the Deep link generator API to create short and long deep links for your apps, individually or in bulk. These customized deep links enhance the user experience across various platforms.

Before you begin

Here’s what you need to know before getting started.

Availability

  • You need to be on the TrueLink Core or Enterprise package to get access to the Deep link generator API.
  • Links created using the Deep link generator API aren’t displayed in Campaign Lab.
  • The TTL (time-to-live) for short links created with the Deep link generator API is 120 days.

Requirements

  1. Admin, Editor, or Custom Editor permissions.
  2. Set up the same branded domain for your iOS and Android app.
    • For iOS apps, ensure that you add your branded domain as an Associated Domain. This sets the domain to be configured as a Universal Link.
    • For Android apps, ensure that you define your branded domain as the Android App Link.
  3. You need a valid custom link token to generate deep links:
  4. Update the Adjust SDK to resolve short links.
  5. If you’ve set up data residency, make sure you are using the same region for your iOS and Android apps.

Rate Limiting

To ensure optimal performance and fair usage across all clients, the Deep link generator API enforces the following rate limits:

  1. Per-app limit for short link creation:
    • Up to 50 requests per second for creating short links for a single app.
    • For bulk link creation requests, up to 100 requests per 2 seconds.
  2. Per-account limit for all link creation and update operations:
    • Up to 200 requests per second across all apps within a single account.

If you exceed any of these limits, the API will respond with a 429 Too Many Requests status. After receiving this response, you must wait until the rate limit window resets before retrying your request.

To avoid hitting these limits, especially in high-throughput scenarios, we recommend implementing:

  • Automatic retry logic with an exponential backoff strategy to progressively increase the delay between retries.
  • Global concurrency control to effectively limit the number of concurrent requests, such as:
    • asyncio.Semaphore in Python
    • async-sema in Node.js
    • or Semaphore from java.util.concurrent in Java

Proper rate limit handling is essential for maintaining uninterrupted service access and avoiding throttling.

Authentication

Access to the Deep link generator API requires providing an Adjust API token via the Authorization header (Bearer token).

If your organization has enabled Single Sign-On (SSO), contact your Adjust representative or email support@adjust.com for help with finding your API token.

For non-SSO accounts, API tokens are located in a user’s profile. To find your token, follow these steps:

  1. Select the account (user) icon.
  2. Select Account settings.
  3. Select the My profile tab.
  4. Your API Token is shown with your User Details. Select the copy button to copy the token to your system clipboard.

Reset your Adjust API token

You can reset your Adjust API token at any time. When you do so, the previous token becomes invalid. Make sure to update the token everywhere it is used, as any requests made with an invalidated token will be rejected by Adjust.

To reset your Adjust API token:

  1. Select the account (user) icon.
  2. Select Account settings.
  3. Select the My Profile tab.
  4. Your API Token is shown with your User details.
  5. Select Reset API token.
  6. Enter your account password in the modal that appears and select Reset to reset your API token. A confirmation appears in the top right of the screen.
  7. Select the copy button next to the API Token to copy the token to your system clipboard.

Quota and Usage

The Deep link generator API allows generating an unlimited number of long links, while the number of short links is subject to your contract terms.

  • Only unique short links count against your quota. If the same set of parameters is sent multiple times, the quota is only reduced once.
  • Your short link quota is defined in your contract.
  • When the quota is exhausted or the contract expires, the API will automatically fall back to generating long links, regardless of the shorten_url parameter value.

Requesting current quota information

Execute the following request to retrieve your current quota balance. The response reflects your balance in real time.

Endpoint: https://automate.adjust.com/engage/deep-links/quota

Method: GET

Response: Quota Data

Response headers

Most API responses include headers that provide real-time visibility into your short link quota and contract status:

Response Headers
X-ShortLink-Quota-Limit: 100000 # Total short link quota allocated
X-ShortLink-Quota-Remaining: 86129 # Remaining short link generations
X-Contract-Status: active # Current contract status. One of: "active", "inactive". "inactive" is returned when the contract has ended or the contract information is not yet available
X-Contract-End-Date: 2025-12-31 # Contract expiration date
X-Contract-Start-Date: 2024-12-31 # Contract start date

Generate a single deep link

This operation allows you to generate a long or short deep link for a single-platform, multi-platform, or combined app configuration. Use this when you need to create a single deep link dynamically.

API Protocol

Endpoint: https://automate.adjust.com/engage/deep-links

Method: POST

Request body: Link Generation Payload

Response: HTTP 200 with a Deep-Link object on success. Invalid payloads return HTTP 400 with an Error Response.

Examples

Single-platform apps

Request - cURL
curl --location 'https://automate.adjust.com/engage/deep-links' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer adjustApiToken' \
--data '{
"link_token": "1c52mluz",
"redirect": "https://example.com/redirect",
"fallback": "https://example.com/fallback",
"deep_link_path": "/custom-path"
}'
Response
{
"url": "https://example.go.link/czWsH",
"long_url": "https://example.go.link/custom-path?adj_t=1c52mluz&adj_fallback=https%3A%2F%2Fexample.com%2Ffallback&adj_redirect=https%3A%2F%2Fexample.com%2Fredirect"
}

Multi-platform apps

Request - cURL
curl --location 'https://automate.adjust.com/engage/deep-links' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer adjustApiToken' \
--data '{
"link_token": "1c1zm8r9",
"redirect": "https://example.com/redirect",
"fallback": "https://example.com/fallback",
"android_deep_link_path": "/custom-path",
"redirect_macos": "https://www.example.com/redirectmacos"
}'
Response
{
"url": "https://example.go.link/8oBfZ",
"long_url": "https://example.go.link?adj_t=1c1zm8r9&adj_deep_link=adjustdeeplinks%3A%2F%2Fcustom-path&adj_fallback=https%3A%2F%2Fexample.com%2Ffallback&adj_redirect=https%3A%2F%2Fexample.com%2Fredirect&adj_redirect_macos=https%3A%2F%2Fwww.example.com%2Fredirectmacos"
}

Combined links

Request - cURL
curl --location 'https://automate.adjust.com/engage/deep-links' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer adjustApiToken' \
--data '{
"link_token": "1c2n7ybx_1cjet4nl",
"redirect": "https://example.com/redirect",
"fallback": "https://example.com/fallback",
"ios_deep_link_path": "/custom-path-ios",
"android_deep_link_path": "/custom-path-android",
"redirect_macos": "https://www.example.com/redirectmacos"
}'
Response
{
"url": "https://example.go.link/j55JZ",
"long_url": "https://example.go.link/custom-path-ios?adj_t=1c2n7ybx_1cjet4nl&adj_deep_link=example%3A%2F%2Fcustom-path-android&adj_fallback=https%3A%2F%2Fexample.com%2Ffallback&adj_redirect=https%3A%2F%2Fexample.com%2Fredirect&adj_redirect_macos=https%3A%2F%2Fwww.example.com%2Fredirectmacos"
}

Generating long links only (doesn’t consume short-link quota)

Request - cURL
curl --location 'https://automate.adjust.com/engage/deep-links' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer adjustApiToken' \
--data '{
"link_token": "1c52mluz",
"redirect": "https://example.com/redirect",
"fallback": "https://example.com/fallback",
"deep_link_path": "/custom-path",
"shorten_url": false
}'
Response
{
"url": "https://example.go.link/custom-path?adj_t=1c52mluz&adj_fallback=https%3A%2F%2Fexample.com%2Ffallback&adj_redirect=https%3A%2F%2Fexample.com%2Fredirect",
"long_url": "https://example.go.link/custom-path?adj_t=1c52mluz&adj_fallback=https%3A%2F%2Fexample.com%2Ffallback&adj_redirect=https%3A%2F%2Fexample.com%2Fredirect"
}

Generating short link with a custom short token (link suffix / custom suffix)

Request - cURL
curl --location 'https://automate.adjust.com/engage/deep-links' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer adjustApiToken' \
--data '{
"link_token": "1c52mluz",
"deep_link_path": "/custom-path",
"short_token": "custom-token",
"redirect_macos": "https://www.example.com/redirectmacos"
}'
Response
{
"url": "https://example.go.link/custom-token",
"long_url": "https://example.go.link/custom-path?adj_t=1c52mluz&adj_redirect_macos=https%3A%2F%2Fwww.example.com%2Fredirectmacos"
}

Generate deep links in bulk

Use this operation to generate multiple deep links in a single request. It supports both long and short links for various app types. Use bulk generation to optimize performance and reduce request overhead when creating up to 100 links at once.

API Protocol

Endpoint: https://automate.adjust.com/engage/deep-links/bulk

Method: POST

Request body:

ParameterData type
data*Array[Link Generation Payload]

Response:

ParameterData type
data*Array[Deep-Link or Error Response]

Response statuses:

  • 200 OK — the request payload is valid and every item was created. data is an array of Deep-Link objects, in request order.
  • 207 Multi-Status — the request payload is valid, but one or more items failed during creation. data has one element per request item, in the same order:
    • Deep-Link (url, long_url) — the item was created. Don’t resubmit it.
    • Error Response (error_code, error_desc) — that item failed. Retry only that index.
  • 400 Bad Request — the request payload is invalid. No item is created. Fix the body using error_desc_details and resubmit the whole request.

Example

Request - cURL
curl --location 'https://automate.adjust.com/engage/deep-links/bulk' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer adjustApiToken' \
--data '{
"data": [
{
"link_token": "1doptv0c",
"redirect": "https://example.com/redirect",
"fallback": "https://example.com/fallback",
"campaign": "custom-campaign"
},
{
"link_token": "ERRORDATA"
},
{
"link_token": "1df3xslh_1dsykkaa",
"redirect": "https://example.com/redirect",
"fallback": "https://example.com/fallback",
"ios_deep_link_path": "/custom-path-ios",
"android_deep_link_path": "/custom-path-android"
},
{
"link_token": "1dzwtdjt",
"redirect": "https://example.com/redirect",
"fallback": "https://example.com/fallback",
"android_deep_link_path": "/custom-path"
}
]
}'
Response - HTTP 207
{
"data": [
{
"url": "https://example.go.link/4IlkC",
"long_url": "[CORRESPONDING LONG URL]"
},
{
"error_code": "service_error",
"error_desc": "[ERROR MESSAGE]"
},
{
"url": "https://example.go.link/6KnoE",
"long_url": "[CORRESPONDING LONG URL]"
},
{
"url": "https://example.go.link/5JmnD",
"long_url": "[CORRESPONDING LONG URL]"
}
]
}

The payload was accepted. Item 1 has an Error Response; items 0, 2, and 3 were created, so the status is 207. If every item succeeded, the status would be 200. A 400 response would reject the entire batch and return a single Error Response instead of data.

This operation allows you to retrieve metadata about a previously generated short link, such as its expiration date and redirect parameters. Use this to inspect or verify short link state.

Endpoint: https://automate.adjust.com/engage/deep-links/short-link?short_token={short_token}&app_token={app_token}

Method: GET

Response: Short Token Metadata

Request - cURL
curl --location --request GET 'https://automate.adjust.com/engage/deep-links/short-link?short_token=4IlkC&app_token=zgvhg75bw83k' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer adjustApiToken'
Response
{
"created_at": "2025-03-19T13:31:31Z",
"expires_at": "2025-10-08T17:04:24.201134367Z",
"token": "4IlkC",
"ulink": "example",
"url": "https://example.go.link/?adj_t=1g41cvql_1gb5zq24&adj_fallback=https%3A%2F%2Fexample.com%2Ffallback-1&adj_redirect=https%3A%2F%2Fexample.com%2Fredirect"
}

Use this operation to update the redirect target (long link) of an existing short link. The short link itself remains unchanged.

Endpoint: https://automate.adjust.com/engage/deep-links/{short_token}

Method: PUT

Request body: Link Generation Payload

Response: HTTP 204 No Content on success

Request - cURL
curl --location --request PUT 'https://automate.adjust.com/engage/deep-links/4IlkC' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer adjustApiToken' \
--data '{
"link_token": "1doptv0c",
"redirect": "https://example.com/new-redirect",
"fallback": "https://example.com/new-fallback",
"deep_link_path": "/new-custom-path"
}'
Response
204 No Content

Data Models

ParameterData typeDescription
link_token*StringThe link token from your custom link. Can be a single token, or multiple tokens combined in the form: linkTokenA_linkTokenB.
shorten_urlBooleanIndicates whether the link should be shortened. Default is true.
short_tokenStringA custom short token (link suffix / custom suffix). Use this parameter to generate a short link with a predefined value. For example, if you pass campaign2026, the resulting link will be example.go.link/campaign2026. The token must be unique within one branded domain. Each path segment must be at least two characters. For example, c/2026 is invalid because c is a single-character segment; campaign/2026 is valid.
campaignStringThe custom name of the campaign. Use this parameter to override value from the Custom Link.
adgroupStringThe custom name of the adgroup. Use this parameter to override value from the Custom Link.
creativeStringThe custom name of the creative. Use this parameter to override value from the Custom Link.
deep_link_pathStringSpecifies the in-app destination users are taken to. Use this for single-platform apps.
ios_deep_link_pathStringSpecifies the iOS in-app destination your users are taken to. Use this for multi-platform iOS apps or combined links.
android_deep_link_pathStringSpecifies the Android in-app destination your users are taken to. Use this for multi-platform Android apps or combined links.
web_deep_link_urlStringSpecifies the web URL destination that your users are taken to, instead of requiring app deep-link paths.
web_onlyBooleanWhen set to true, the generated links are converted to web-only format by adding a /w prefix to the URL path (for example, https://example.go.link/custom-path becomes https://example.go.link/w/custom-path). Web-only Links never open the app, even if it’s installed. Instead, they always redirect users to a web destination or app store (as defined the redirect parameter). Requires a branded domain to be configured. Default is false.
fallbackStringLanding page for off-platform users. When you specify a fallback URL, we recommend also specifying redirect_macos and redirect_windows.
fallback_clickBooleanWhen set to true, Adjust considers the link for attribution only if no other preceding eligible click is available. Use this to attribute users who previously engaged with one of your ads to that ad, instead of to this link. Default is false. See Fallback attribution logic for details.
redirectStringRedirect URL to override Adjust’s default redirect.
redirect_iosStringRedirect URL that overrides Adjust’s default redirect for iOS apps only. Use this for multi-platform iOS apps or combined links.
redirect_androidStringRedirect URL that overrides Adjust’s default redirect for Android apps only. Use this for multi-platform Android apps or combined links.
redirect_macosStringRedirect URL to override Adjust’s default redirect for macOS. When you specify the fallback, it’s recommended to specify this parameter for macOS users.
redirect_windowsStringRedirect URL to override Adjust’s default redirect for Windows. When you specify the fallback, it’s recommended to specify this parameter for Windows users.
labelStringAdds custom data to the link. Use this parameter to add a unique user referral ID that’s autopopulated when a user shares a short link from your app.
custom_dynamic_callback_parametersObjectKey-value callback parameters appended to the generated URL query string without the adj_ prefix. Both keys and values are URL-encoded automatically.
og_titleStringTitle of the social sharing preview of the link. Required if any OG field is set.
og_descriptionStringDescription of the social sharing preview of the link. Optional even when other OG fields are set.
og_imageStringURL to a JPG or PNG image of at least 200 x 200 pixels size for the social sharing preview of the link. Required if any OG field is set.
ParameterData typeDescription
url*StringFinal link: short or long
long_url*StringCorresponding long link

Short Token Metadata

ParameterData typeDescription
created_at*StringISO datetime object
expires_at*StringISO datetime object of the short link expiration date
updated_atStringISO datetime object of the last link update
token*StringToken
ulink*StringBranded domain
url*StringFull long link

Quota Data

ParameterData typeDescription
limit*IntegerTotal short link quota allocated
remaining*IntegerRemaining short link generations
contract_status*StringCurrent contract status. One of: “active”, “inactive”. “inactive” is returned when the contract has ended or the contract information is not yet available.
contract_start_dateStringISO date object. Contract start date.
contract_end_dateStringISO date object. Contract expiration date.

Custom Dynamic Callback Parameters

Dynamic callback parameters (DCPs) let you send custom campaign parameters at click or impression time. Use them to collect user-specific data for your internal system and receive network partner macros beyond Adjust’s campaign parameters. These custom parameters are also available as part of the Full click URL and hence retrievable within your app and used for deep linking into specific content, orchestrating any custom experiences etc.

Example

Request - cURL
curl --location 'https://automate.adjust.com/engage/deep-links' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer adjustApiToken' \
--data '{
"link_token": "1c52mluz",
"redirect": "https://example.com/redirect",
"fallback": "https://example.com/fallback",
"deep_link_path": "/custom-path",
"custom_dynamic_callback_parameters": {
"coupon_code": "SUMMER_2026",
"affiliate_id": "partner 42",
"source_page": "home/banner"
}
}'
Response
{
"url": "https://example.go.link/7XpQr",
"long_url": "https://example.go.link/custom-path?adj_t=1c52mluz&adj_fallback=https%3A%2F%2Fexample.com%2Ffallback&adj_redirect=https%3A%2F%2Fexample.com%2Fredirect&coupon_code=SUMMER_2026&affiliate_id=partner%2042&source_page=home%2Fbanner"
}

Error Response

ParameterData typeDescription
error_codeStringError code: request_error, auth_error, validation_error, service_error
error_descStringHuman-readable error description
error_desc_detailsArrayAdditional validation metadata, including the field path in loc.

When present, each error_desc_details item includes:

FieldData typeDescription
typeStringValidation error type, for example value_error or missing.
locArrayPath to the invalid field. See loc format.
msgStringHuman-readable validation message.

loc format

loc is a JSON array that identifies the invalid field.

  • Bulk body (POST /deep-links/bulk): ["body", "data", <zero-based item index>, "<field_name>"]. For example, ["body", "data", 1, "link_token"] points to the second item (data[1]), field link_token.
  • Single body (POST /deep-links): ["body", "<field_name>"]. For example, ["body", "short_token"].

How to retry

  1. HTTP 400 — the request payload is invalid. Nothing was created. Use loc to find the field (and, for bulk, the item index), fix them, and resubmit the whole request.
  2. HTTP 207 on bulk — the payload was accepted, but some items failed during creation. Walk data by index. Retry only elements that have error_code. Don’t resubmit items that have url.
  3. HTTP 200 on bulk — every item was created. Don’t retry.
HTTP 400 example
{
"error_code": "validation_error",
"error_desc": "The request has 1 validation error",
"error_desc_details": [
{
"type": "value_error",
"loc": ["body", "data", 1, "link_token"],
"msg": "Value error, `link_token` cannot be empty string"
}
]
}