Lewati ke konten utama
s.id Logo
Lihat Markdown

API v2 Shortener

Buat dan kelola link pendek dari aplikasi kamu. Base URL: https://api.s.id/v2. Versi saat ini 2.0.0, dan spesifikasi lengkapnya tersedia dalam format OpenAPI.

Referensi interaktif

Autentikasi

Kirim API key sk_live_... atau access token OAuth 2.0 lewat header Authorization: Bearer. API key dibuat di Dashboard > Developer, dan setiap key hanya bisa memakai scope yang kamu pilih.

ScopeAkses
links:readLihat daftar dan detail link
links:writeBuat dan perbarui link (buat, edit, pulihkan)
links:archiveArsipkan link
links:analyticsLihat statistik klik per link dan jumlah sepanjang waktu
http
Authorization: Bearer sk_live_...

Panduan lengkap autentikasi

Kirim POST /links dengan URL tujuan. Slug dibuat otomatis jika custom_slug tidak diisi.

bash
curl -X POST https://api.s.id/v2/links \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"long_url": "https://example.com/long-url", "custom_slug": "[your-alias]"}'
FieldTipeWajibKeterangan
long_urlstringYaURL tujuan
titlestringTidakJudul link
custom_slugstringTidakSlug kustom; dibuat otomatis jika kosong
passwordstringTidakKata sandi untuk melindungi link
expired_atintegerTidakWaktu kedaluwarsa dalam Unix timestamp (detik)
domain_aliasstringTidakDomain kustom sebagai pengganti s.id

Contoh respons:

json
{
  "data": {
    "id": 123,
    "short": "[your-alias]",
    "short_url": "https://s.id/[your-alias]",
    "long_url": "https://example.com/long-url",
    "microsite": false,
    "protected": false,
    "disposable": false,
    "adult": false
  },
  "message": "link_created"
}

Daftar endpoint

Hanya disimpan di halaman ini sampai Anda memuat ulang. Hapus setelah selesai.

User

GET/user

Base URL: https://api.s.id/v2 · Scope: user:read

Respons

KodeKeterangan
200User profile
401Missing or invalid API key
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: user:read

Simpan API key kamu di atas untuk mengirim request.

GET/quota

Returns the authenticated user's current plan limits and usage counters.

Base URL: https://api.s.id/v2 · Scope: user:read

Respons

KodeKeterangan
200Account quota
401Missing or invalid API key
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: user:read

Simpan API key kamu di atas untuk mengirim request.

QR

GET/qr

Returns the account-level (global) QR code settings applied to QR codes by default.

Base URL: https://api.s.id/v2 · Scope: qr:read

Respons

KodeKeterangan
200Global QR settings
401Missing or invalid API key
403API key lacks the required scope
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: qr:read

Simpan API key kamu di atas untuk mengirim request.

PUT/qr

Updates the account-level (global) QR code settings. All fields are optional; omitted fields are left unchanged.

Base URL: https://api.s.id/v2 · Scope: qr:write

Body request

FieldTipeWajibKeterangan
logostringTidakURL of the logo image embedded in the QR code
colorstringTidakForeground color as a hex value, e.g. #1a56db

Respons

KodeKeterangan
200Updated global QR settings
401Missing or invalid API key
403API key lacks the required scope
422Request validation failed
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: qr:write

Simpan API key kamu di atas untuk mengirim request.

GET/links/{short}/qr

Returns the QR code settings for a single link.

Base URL: https://api.s.id/v2 · Scope: qr:read

Parameter

FieldLokasiTipeWajibKeterangan
shortpathstringYaThe short code of the link

Respons

KodeKeterangan
200Link QR settings
401Missing or invalid API key
403API key lacks the required scope
404Resource not found
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: qr:read

Simpan API key kamu di atas untuk mengirim request.

PUT/links/{short}/qr

Updates the QR code settings for a single link. All fields are optional; omitted fields are left unchanged.

Base URL: https://api.s.id/v2 · Scope: qr:write

Parameter

FieldLokasiTipeWajibKeterangan
shortpathstringYaThe short code of the link

Body request

FieldTipeWajibKeterangan
logostringTidakURL of the logo image embedded in the QR code
colorstringTidakForeground color as a hex value, e.g. #1a56db

Respons

KodeKeterangan
200Updated link QR settings
401Missing or invalid API key
403API key lacks the required scope
404Resource not found
422Request validation failed
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: qr:write

Simpan API key kamu di atas untuk mengirim request.

Microsites

GET/microsites

Returns a paginated list of microsites owned by the authenticated user.

Base URL: https://api.s.id/v2 · Scope: microsites:read

Parameter

FieldLokasiTipeWajibKeterangan
limitqueryintegerTidak
afterquerystringTidakCursor for the next page (opaque string from previous response)

Respons

KodeKeterangan
200List of microsites
401Missing or invalid API key
403API key lacks the required scope
Coba APIScope: microsites:read

Simpan API key kamu di atas untuk mengirim request.

POST/microsites

Base URL: https://api.s.id/v2 · Scope: microsites:write

Body request

FieldTipeWajibKeterangan
slugstringYaURL-safe identifier (alphanumeric + hyphens/underscores)
titlestringYa
kindstringYaMicrosite category (e.g. personal_branding, brand, other)
themestringTidakTheme slug (optional, defaults to the platform default)

Respons

KodeKeterangan
200Microsite created
400Validation error (slug already taken, quota exceeded, etc.)
401Missing or invalid API key
403API key lacks the required scope
Coba APIScope: microsites:write

Simpan API key kamu di atas untuk mengirim request.

GET/microsites/{slug}

Base URL: https://api.s.id/v2 · Scope: microsites:read

Parameter

FieldLokasiTipeWajibKeterangan
slugpathstringYa

Respons

KodeKeterangan
200Microsite detail
401Missing or invalid API key
403API key lacks the required scope
404Microsite not found
Coba APIScope: microsites:read

Simpan API key kamu di atas untuk mengirim request.

PUT/microsites/{slug}

Patches title, description, and/or visibility. All fields are optional.

Base URL: https://api.s.id/v2 · Scope: microsites:write

Parameter

FieldLokasiTipeWajibKeterangan
slugpathstringYa

Body request

FieldTipeWajibKeterangan
titlestringTidak
descriptionstringTidak
hidebooleanTidakSet true to hide the microsite from public (requires plan that supports visibility toggle)

Respons

KodeKeterangan
200Updated microsite
401Missing or invalid API key
403API key lacks the required scope
404Microsite not found
Coba APIScope: microsites:write

Simpan API key kamu di atas untuk mengirim request.

DELETE/microsites/{slug}

Base URL: https://api.s.id/v2 · Scope: microsites:delete

Parameter

FieldLokasiTipeWajibKeterangan
slugpathstringYa

Respons

KodeKeterangan
200Microsite deleted
401Missing or invalid API key
403API key lacks the required scope
404Microsite not found
Coba APIScope: microsites:delete

Simpan API key kamu di atas untuk mengirim request.

POST/microsites/available

Checks whether a microsite slug is available before creating a microsite.

Base URL: https://api.s.id/v2 · Scope: microsites:read

Body request

FieldTipeWajibKeterangan
slugstringYa

Respons

KodeKeterangan
200Slug availability result
401Missing or invalid API key
403API key lacks the required scope
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: microsites:read

Simpan API key kamu di atas untuk mengirim request.

GET/microsites/{slug}/components

Returns the components belonging to a microsite, in display order.

Base URL: https://api.s.id/v2 · Scope: microsites:read

Parameter

FieldLokasiTipeWajibKeterangan
slugpathstringYaThe slug of the microsite

Respons

KodeKeterangan
200List of microsite components
401Missing or invalid API key
403API key lacks the required scope
404Resource not found
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: microsites:read

Simpan API key kamu di atas untuk mengirim request.

POST/microsites/{slug}/components

Adds a new component to a microsite. The body is { kind, data, tag? }. The shape of the data object depends on kind. Unknown fields are ignored, validation is per-kind, and invalid input returns 422. All color fields are hex strings (e.g. #1a56db). **Kinds:** PROFILE, LINK, HORIZONTAL_LINK, TEXT, IMAGE, MEDIA, DIVIDER, COUNTDOWN, MAPS, IMAGE_SLIDE, CV, AUTOPLAY_MUSIC, CONTACT, CALENDAR, SHOP_LISTING, SHOP_ITEM, SHOP_LEADERBOARD. **Rules:** - PROFILE, CV and AUTOPLAY_MUSIC are unique — at most one per microsite. - IMAGE_SLIDE requires a plan with the Image Slide feature. - On create the password is always stored empty — set or change it via update (PUT). - Image fields (image, imageBackground, slide image) must be a local asset path, not a remote URL — they must match [/.a-zA-Z0-9_-]+.(jpg|jpeg|png|svg|webp|gif|bmp); any value containing a scheme (https://), //, or .. is rejected. **Shared field groups** (a kind that lists a group accepts all of its fields inside data): - **Button styling** (LINK, CONTACT, CALENDAR): icon (string, max 255), textFont (string, max 100), textPosition (string, max 100), buttonEffect (string, max 100), buttonColor (hex, max 20), buttonBorderColor (hex, max 20), buttonIconBackground (hex, max 20), buttonShadowColor (hex, max 20). - **Spoiler reveal** (TEXT, IMAGE, MEDIA, MAPS, IMAGE_SLIDE, SHOP_LEADERBOARD): isSpoiler (bool), spoilerButtonText (string, max 140), spoilerButtonTextPosition (string, max 100), spoilerButtonIcon (string), spoilerButtonColor (hex, max 20), spoilerButtonFont (string, max 100), spoilerBackground (string, max 100), spoilerBackgroundOpacity (string, max 100), spoilerButtonBorderColor (hex, max 20), spoilerButtonIconBackground (hex, max 20), spoilerButtonShadowColor (hex, max 20). - **Password protection** (LINK, TEXT, IMAGE, MEDIA, MAPS, IMAGE_SLIDE, CONTACT, CV, SHOP_LEADERBOARD): passwordActive (bool), password (string, max 255 — set via update only), passwordMessage (string, max 255).

Base URL: https://api.s.id/v2 · Scope: microsites:write

Parameter

FieldLokasiTipeWajibKeterangan
slugpathstringYaThe slug of the microsite

Body request

FieldTipeWajibKeterangan
kindPROFILE | LINK | HORIZONTAL_LINK | TEXT | IMAGE | MEDIA | DIVIDER | COUNTDOWN | MAPS | IMAGE_SLIDE | CV | AUTOPLAY_MUSIC | CONTACT | CALENDAR | SHOP_LISTING | SHOP_ITEM | SHOP_LEADERBOARDYaComponent kind. The shape of data depends on this value.
dataobjectYaKind-specific component data. Its shape depends on kind. See the operation description and examples below.
tagstringTidakOptional grouping tag

Respons

KodeKeterangan
200Component created
401Missing or invalid API key
403API key lacks the required scope
404Resource not found
422Request validation failed
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: microsites:write

Simpan API key kamu di atas untuk mengirim request.

PUT/microsites/{slug}/components/{componentId}

Updates a single microsite component.

Base URL: https://api.s.id/v2 · Scope: microsites:write

Parameter

FieldLokasiTipeWajibKeterangan
slugpathstringYaThe slug of the microsite
componentIdpathstringYaThe component ID

Body request

FieldTipeWajibKeterangan
activebooleanYaWhether the component is shown
kindstringYaComponent kind (e.g. LINK, PROFILE, TEXT)
dataobjectYaKind-specific component data

Respons

KodeKeterangan
200Component updated
401Missing or invalid API key
403API key lacks the required scope
404Resource not found
422Request validation failed
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: microsites:write

Simpan API key kamu di atas untuk mengirim request.

DELETE/microsites/{slug}/components/{componentId}

Deletes a single microsite component.

Base URL: https://api.s.id/v2 · Scope: microsites:delete

Parameter

FieldLokasiTipeWajibKeterangan
slugpathstringYaThe slug of the microsite
componentIdpathstringYaThe component ID

Respons

KodeKeterangan
200Component deleted
401Missing or invalid API key
403API key lacks the required scope
404Resource not found
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: microsites:delete

Simpan API key kamu di atas untuk mengirim request.

POST/microsites/{slug}/components/order

Reorders a microsite's components according to the provided list of component IDs.

Base URL: https://api.s.id/v2 · Scope: microsites:write

Parameter

FieldLokasiTipeWajibKeterangan
slugpathstringYaThe slug of the microsite

Body request

FieldTipeWajibKeterangan
ordersstring[]YaComponent IDs in the desired display order

Respons

KodeKeterangan
200Components reordered
401Missing or invalid API key
403API key lacks the required scope
404Resource not found
422Request validation failed
429Too many requests. Per-tier limits apply, resolved from your s.id plan: a per-credential per-minute rate limit (rate_limit_exceeded) and a daily call quota (api_quota_exceeded), both shared across every integration using your credential (sk_live_* key or OAuth token). OAuth apps also have a secondary per-client_id ceiling (client_rate_limit_exceeded) across all their users' tokens. See GET /v2/quota for your current standing, and the X-RateLimit-* / X-Quota-* response headers.
Coba APIScope: microsites:write

Simpan API key kamu di atas untuk mengirim request.

OAuth 2.0

GET/oauth/authorize

A plain browser navigation here (no Accept: application/json) 302-redirects to the dash.s.id consent UI, preserving the query string. With Accept: application/json, returns application name, logo, and requested scopes for the consent UI to render.

Base URL: https://api.s.id

Parameter

FieldLokasiTipeWajibKeterangan
client_idquerystringYa
redirect_uriquerystringYa
response_typequerycodeYa
scopequerystringTidak
statequerystringTidakRecommended. Opaque value for CSRF protection. Returned unchanged in the redirect.

Respons

KodeKeterangan
200Consent screen data
400Bad request
POST/oauth/token

Base URL: https://api.s.id

Body request

FieldTipeWajibKeterangan
grant_typeauthorization_code | refresh_tokenTidak
codestringTidak
redirect_uristringTidak
client_idstringTidak
client_secretstringTidak
refresh_tokenstringTidak

Respons

KodeKeterangan
200Token response
400Invalid grant, unsupported_grant_type, or invalid_client
401Invalid client credentials
POST/oauth/revoke

Revokes an access or refresh token. Always returns 200 OK regardless of whether the token was valid (RFC 7009).

Base URL: https://api.s.id

Body request

FieldTipeWajibKeterangan
tokenstringYa

Respons

KodeKeterangan
200Token revoked
POST/oauth/introspect

Reports whether a token is currently active and, if so, which scopes and client it belongs to (RFC 7662). Client-credential protected: client_id/client_secret identify the caller, not the token owner. Always returns 200 — including for an unknown, expired, or revoked token ({"active": false}) — to avoid leaking token validity to unauthenticated probing.

Base URL: https://api.s.id

Body request

FieldTipeWajibKeterangan
tokenstringYa
client_idstringYa
client_secretstringYa

Respons

KodeKeterangan
200Introspection result
400Missing token/client_id, or invalid client credentials
GET/oauth/userinfo

Returns the profile of the user who authorized the OAuth app. Requires Authorization: Bearer <access_token> (the OAuth access token, not an sk_live_ key).

Base URL: https://api.s.id · Scope: user:read

Respons

KodeKeterangan
200User profile
401Unauthorized
GET/.well-known/oauth-authorization-server

RFC 8414 discovery document advertising every OAuth endpoint URL, supported scopes, and PKCE methods, so standards-compliant client libraries can configure themselves instead of hard-coding s.id's URLs.

Base URL: https://api.s.id

Respons

KodeKeterangan
200Authorization server metadata
GET/api/user/oauth/apps

Returns all OAuth clients that have active tokens for the authenticated user. Auth: user session cookie (not API key).

Base URL: https://api.s.id

Respons

KodeKeterangan
200List of connected apps
401Unauthorized
DELETE/api/user/oauth/apps/{clientId}

Revokes all active tokens granted by the current user to the specified OAuth client.

Base URL: https://api.s.id

Parameter

FieldLokasiTipeWajibKeterangan
clientIdpathstringYa

Respons

KodeKeterangan
200App access revoked
401Unauthorized
404App not found

Analytics

GET/stats

Returns a timeline of clicks plus breakdowns by top links, referers, locations, devices, and browsers for the authenticated account. Date range is gated by subscription plan.

Base URL: https://api.s.id/v2 · Scope: links:analytics

Parameter

FieldLokasiTipeWajibKeterangan
startquerystringTidakStart date (YYYY-MM-DD). Defaults to 30 days ago.
endquerystringTidakEnd date (YYYY-MM-DD). Defaults to today.
additionalquerybooleanTidakInclude referer, location, device, browser breakdowns

Respons

KodeKeterangan
200Account analytics
401Missing or invalid API key
403API key lacks the required scope
Coba APIScope: links:analytics

Simpan API key kamu di atas untuk mengirim request.

Batas dan error

Setiap kredensial dibatasi per menit. Cek posisi kuota kamu lewat GET /quota.

KredensialBatas
API key atau access token OAuth38 permintaan per menit
Aplikasi OAuth (gabungan semua token)500 permintaan per menit
KodeArtinya
400Permintaan salah format atau tidak didukung
401Kredensial tidak ada, tidak valid, dicabut, atau kedaluwarsa
403Kredensial tidak memiliki scope yang dibutuhkan
404Resource yang diminta tidak ditemukan
422Validasi permintaan gagal
429Batas permintaan terlampaui