Skip to Content

Endpoints

All endpoints share the base path:

https://api.codelloy.com/link/external/v1

Authentication is by X-API-KEY on every request. See Obtaining Your API Key to generate one and Mobile Apps for the deep-link setup that the schema below references via mobileAppId.

Every response is wrapped in the standard envelope { response: …, errors: … } — on success response is the payload and errors is omitted; on failure response is omitted and errors is a non-empty array. See API Errors for the full error catalogue.


Create or Update a Short URL

Creates a new short URL or updates an existing one (matched by shortCode).

POST /link/external/v1/shortenedUrl/save

Request Headers

HeaderValueRequired
X-API-KEYYour API keyYes
Content-Typeapplication/jsonYes

Request Body

FieldTypeRequiredDescription
urlstringYesDestination URL. Must be non-empty.
shortCodestringNoCustom alias for the short link. 7–50 characters, alphanumeric / hyphen / underscore only (regex ^[a-zA-Z0-9_-]{7,50}$). Auto-generated when omitted. Re-using an existing shortCode belonging to your organisation updates that record.
shortLinkNamestringNoHuman-readable label shown in the dashboard list view. Strongly recommended for API-created links so operators can find them.
isActivebooleanNoDefaults to true. Set to false to archive the link without deleting it (clients get HTTP 410 EN002 at click time).
utmSourcestringNoUTM source tag (appended to the destination URL at click time).
utmCampaignstringNoUTM campaign tag.
utmMediumstringNoUTM medium tag.
enableCustomMetadatabooleanNoWhen true, the customMetadata* fields below override the destination URL’s Open Graph preview for social-sharing surfaces. Requires the Metadata Preview feature on your plan.
customMetadataTitlestringNoOverride title for link previews.
customMetadataDescriptionstringNoOverride description for link previews.
customMetadataImageUrlstringNoOverride image URL for link previews.
deepLinksarrayNoArray of DeepLink objects (see sub-table below). Omit or pass [] for a plain redirect-only short URL.

DeepLink Entry Schema

Each entry in the deepLinks[] array follows this shape.

FieldTypeDirectionDescription
mobileAppIdstringRequired on requestThe 12-character ID from your Manage Apps dashboard. Identifies the registered MobileApp this entry targets. Null/blank/unknown values return DL001.
deeplinkUrlstringRequestCustom-scheme URI used when the app is installed (e.g. myapp://product/123).
fallbackUrlstringRequestWeb URL used when fallbackEnabled=true and the app is not installed.
linkBehaviourstringRequest"app" (try the deep link first) or "webBrowser" (skip the app and go straight to url).
fallbackEnabledbooleanRequestWhen true, prefer fallbackUrl over the registered Store URL on app-not-installed. When false, prefer the Store URL.
platformstringResponse only — server-controlledReflects the registered MobileApp.platform ("IOS" / "ANDROID" / "WEB"). Values supplied in the request body are silently overwritten on save.
storeUrlstringResponse only — server-controlledReflects the registered MobileApp.storeUrl at read time. Edits via Manage Apps are picked up immediately on the next read.

Example Request

curl -X POST https://api.codelloy.com/link/external/v1/shortenedUrl/save \ -H "X-API-KEY: your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/product/123", "shortCode": "spring-sale", "shortLinkName": "Spring sale — product 123", "deepLinks": [ { "mobileAppId": "abc123def456", "deeplinkUrl": "myapp://product/123", "fallbackUrl": "https://example.com/product/123", "linkBehaviour": "app", "fallbackEnabled": true }, { "mobileAppId": "789xyz456ghi", "deeplinkUrl": "myapp://product/123", "fallbackUrl": "https://example.com/product/123", "linkBehaviour": "app", "fallbackEnabled": true } ] }'

Success Response

HTTP/1.1 200 OK Content-Type: application/json
{ "response": { "url": "https://example.com/product/123", "shortCode": "spring-sale", "shortLinkName": "Spring sale — product 123", "smartLink": "https://re.codelloy.com/spring-sale", "isActive": true, "deepLinks": [ { "mobileAppId": "abc123def456", "platform": "IOS", "storeUrl": "https://apps.apple.com/app/myapp/id123456789", "deeplinkUrl": "myapp://product/123", "fallbackUrl": "https://example.com/product/123", "linkBehaviour": "app", "fallbackEnabled": true, "appId": 42 }, { "mobileAppId": "789xyz456ghi", "platform": "ANDROID", "storeUrl": "https://play.google.com/store/apps/details?id=com.example.myapp", "deeplinkUrl": "myapp://product/123", "fallbackUrl": "https://example.com/product/123", "linkBehaviour": "app", "fallbackEnabled": true, "appId": 43 } ], "createdAt": "2026-05-15T10:30:00", "updatedAt": "2026-05-15T10:30:00", "createdBy": "api-key:Production Integration", "updatedBy": "api-key:Production Integration", "createdVia": "EXTERNAL", "lastModifiedVia": "EXTERNAL" } }

Custom domains: smartLink reflects your organisation’s active custom domain when the link is created (e.g. https://go.yourbrand.com/spring-sale). If the custom domain is later removed, https://re.codelloy.com/{shortCode} continues to resolve as a fallback.

Audit attribution: createdBy and updatedBy start with api-key: for any write performed through the External API — followed by the label you set on the key (or the default <orgName> API key if you didn’t supply one). See Obtaining Your API Key for the labelling flow.

Validation Errors

A missing required field returns HTTP 400. Bean Validation errors emit SML002; ad-hoc validation (e.g. invalid shortCode format) emits VE001. Branch on the code field, not the HTTP status.

HTTP/1.1 400 Bad Request Content-Type: application/json
{ "errors": [ { "code": "SML002", "message": "must not be empty" } ] }

A deepLinks[] entry with a missing or unknown mobileAppId returns HTTP 400 with DL001:

{ "errors": [ { "code": "DL001", "message": "Deep link entry rejected: mobileAppId 'unknown123' is not recognised for this organisation", "details": { "kind": "deep_link_validation", "mobileAppId": "unknown123" } } ] }

Bulk Create or Update Short URLs

Creates or updates up to 30 short URLs in a single request.

POST /link/external/v1/shortenedUrl/bulkSave

Request Headers

HeaderValueRequired
X-API-KEYYour API keyYes
Content-Typeapplication/jsonYes

Request Body

FieldTypeRequiredDescription
dataarrayYesArray of short-URL objects (same fields as the single save endpoint). Max 30 items.

Example Request

curl -X POST https://api.codelloy.com/link/external/v1/shortenedUrl/bulkSave \ -H "X-API-KEY: your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "data": [ { "url": "https://example.com/page-one", "shortCode": "page-one", "shortLinkName": "Page One" }, { "url": "https://example.com/page-two", "shortLinkName": "Page Two" } ] }'

Success Response

A single envelope wraps two arrays — successRecords (saved) and failureRecords (rejected) — plus a bulkSaveSummary count.

HTTP/1.1 200 OK Content-Type: application/json
{ "response": { "successRecords": [ { "shortCode": "page-one", "url": "https://example.com/page-one", "shortLinkName": "Page One", "smartLink": "https://re.codelloy.com/page-one", "isActive": true, "createdVia": "EXTERNAL", "lastModifiedVia": "EXTERNAL" }, { "shortCode": "a81bb82", "url": "https://example.com/page-two", "shortLinkName": "Page Two", "smartLink": "https://re.codelloy.com/a81bb82", "isActive": true, "createdVia": "EXTERNAL", "lastModifiedVia": "EXTERNAL" } ], "failureRecords": [], "bulkSaveSummary": { "successCount": 2, "failureCount": 0 } } }

Whole-batch validation failure

If the outer payload is malformed (e.g. data missing or empty), the entire request fails with the standard errors[] envelope — no per-record processing happens.

{ "errors": [ { "code": "SML002", "message": "must not be empty" } ] }

List Short URLs

Returns a paginated list of your short URLs. All filtering is via the query DSL parameter (described below).

GET /link/external/v1/shortenedUrl?page={page}&size={size}&query={query}

Request Headers

HeaderValueRequired
X-API-KEYYour API keyYes

Query Parameters

ParameterTypeDefaultDescription
pageinteger0Page number (zero-based).
sizeinteger20Number of results per page.
querystringFilter expression in the Codelloy query DSL (see below).

Example Request

curl -X GET "https://api.codelloy.com/link/external/v1/shortenedUrl?page=0&size=10&query=isActive=true" \ -H "X-API-KEY: your_api_key_here"

Success Response

The response envelope wraps a data[] array of short-URL objects plus a page metadata object with size / number / totalElements / totalPages.

HTTP/1.1 200 OK Content-Type: application/json
{ "response": { "data": [ { "url": "https://example.com/product/123", "shortCode": "spring-sale", "shortLinkName": "Spring sale — product 123", "smartLink": "https://re.codelloy.com/spring-sale", "isActive": true, "enableCustomMetadata": false, "createdAt": "2026-05-15T10:30:00.742912", "updatedAt": "2026-05-15T10:30:00.742912", "createdBy": "api-key:Production Integration", "updatedBy": "api-key:Production Integration", "createdVia": "EXTERNAL", "lastModifiedVia": "EXTERNAL" } ], "page": { "size": 10, "number": 0, "totalElements": 42, "totalPages": 5 } } }

createdAt / updatedAt are serialised as Java LocalDateTime — no trailing Z (no timezone) and microsecond precision. Parse in your client with a LocalDateTime / naive datetime strategy, not an instant-with-zone parser.

Query DSL — Filtering Syntax

The query parameter accepts structured expressions in the form field=value. Multiple expressions can be combined with AND / OR.

FieldTypeExample
urlstringurl=https://example.com/page
shortCodestringshortCode=spring-sale
shortLinkNamestringshortLinkName=Spring sale
smartLinkstringsmartLink=https://re.codelloy.com/abc
isActivebooleanisActive=true
enableCustomMetadatabooleanenableCustomMetadata=true
createdBystringcreatedBy=alice@example.com or createdBy=api-key:Production Integration
updatedBystringSame shape as createdBy.
createdViaenumcreatedVia=EXTERNAL or createdVia=INTERNAL (case-insensitive). Filter for rows created via the External API or the dashboard.
lastModifiedViaenumSame shape as createdVia — match the most recent write source.

Combine expressions with AND (intersection) or OR (union). Whitespace around operators is optional.

# All EXTERNAL-created links that are still active curl -X GET "https://api.codelloy.com/link/external/v1/shortenedUrl?query=createdVia=EXTERNAL AND isActive=true" \ -H "X-API-KEY: your_api_key_here"

Unknown enum values return HTTP 400 VE001 with a “Invalid value ‘X’ for enum ChangeSource” message; valid values are INTERNAL and EXTERNAL.

Last updated on