Appearance
Create Link
Creates a smart link. Beyond inserting a row, create_link scrapes metadata from the supplied Spotify URL, resolves the release across other streaming services, and builds the destination list for you.
The resulting public URL is https://{domain}/{path}.
Arguments
| Argument | Type | Required | Description |
|---|---|---|---|
artist_id | String! | Yes | The ID of the artist. Your account must be attached to this artist. |
domain | String! | Yes | The domain of the link — vibe.to, listen.to, or a custom domain assigned to this artist. |
path | String! | Yes | The path of the link. Minimum three characters, unique within the domain. |
type | String! | Yes | bio, release, or playlist. Must match the kind of Spotify URL supplied. |
spotify_link | String! | Yes | Full open.spotify.com URL. Shortened spotify.link URLs are rejected. |
title | String | No | Defaults to the Spotify release title. |
subtitle | String | No | Defaults to the Spotify artist name. |
description | String | No | Defaults to the Spotify description. |
image | String | No | Preview image. Defaults to the Spotify cover image. |
theme | String | No | light or dark. Defaults to light. |
fill_dsps | Boolean | No | Auto-fill available DSP links (Apple Music, Amazon Music, iTunes, Deezer, TikTok). Defaults to true. Applies to release links only. |
display_artist_socials | Boolean | No | Show the artist's social links. Defaults to true. |
preview_type | String | No | image or spotify. Defaults to image. |
autoplay_track | String | No | Spotify track ID to autoplay. Playlist links only. |
type and spotify_link must agree
create_link validates the Spotify URL against the declared type and rejects mismatches.
type | Accepted Spotify URL |
|---|---|
bio | open.spotify.com/artist/... |
release | open.spotify.com/album/... or open.spotify.com/track/... |
playlist | open.spotify.com/playlist/... |
Domain rules
vibe.to and listen.to are always available. Any other domain must be a custom domain already assigned to the artist, or the call fails with Artist does not have access to the domain. See Domains.
Request
graphql
mutation CreateLink(
$artist_id: String!
$domain: String!
$path: String!
$type: String!
$spotify_link: String!
$title: String
$subtitle: String
$description: String
$image: String
$theme: String
$fill_dsps: Boolean
$display_artist_socials: Boolean
$preview_type: String
$autoplay_track: String
) {
create_link(
artist_id: $artist_id
domain: $domain
path: $path
type: $type
spotify_link: $spotify_link
title: $title
subtitle: $subtitle
description: $description
image: $image
theme: $theme
fill_dsps: $fill_dsps
display_artist_socials: $display_artist_socials
preview_type: $preview_type
autoplay_track: $autoplay_track
) {
success
link {
id
domain
path
artist_id
type
title
subtitle
description
image
theme
display_artist_socials
release_name
preview_type
autoplay_track
layout
destinations {
id
type
url
cta
text
logo
enabled
deeplink_ios
deeplink_android
priority
}
tracks {
id
url
name
priority
}
}
}
}Variables:
json
{
"artist_id": "3aad8009-a307-4429-a586-8b3dbe39cdda",
"domain": "vibe.to",
"path": "example-single",
"type": "release",
"spotify_link": "https://open.spotify.com/album/4uLU6hMCjMI75M1A2tKUQC",
"fill_dsps": true
}Response
json
{
"data": {
"create_link": {
"success": true,
"link": {
"id": "9c4b2f10-...",
"domain": "vibe.to",
"path": "example-single",
"type": "release",
"title": "Example Single",
"subtitle": "Example Artist",
"theme": "light",
"preview_type": "image",
"layout": "2",
"destinations": [
{
"id": "b2d1...",
"type": "spotify",
"url": "https://open.spotify.com/album/4uLU6hMCjMI75M1A2tKUQC",
"cta": "Stream on Spotify",
"text": "Stream on Spotify",
"enabled": true,
"priority": 1
},
{
"id": "c8e4...",
"type": "applemusic",
"url": "https://music.apple.com/us/album/...",
"cta": "Stream on Apple Music",
"enabled": true,
"priority": 2
}
],
"tracks": []
}
}
}
}What happens automatically
Metadata is scraped. title, subtitle, description, and image are read from the Spotify page when you do not supply them. release_name is always set from Spotify regardless of any title you pass.
DSPs are resolved. For type: "release" with fill_dsps left on, ArtistHub looks up the release across Apple Music, Deezer, iTunes, Amazon Music, and TikTok and attaches a destination for each one it finds, with default call-to-action text:
Destination type | Default cta / text | priority |
|---|---|---|
spotify | Stream on Spotify | 1 |
applemusic | Stream on Apple Music | 2 |
deezer | Play on Deezer | 3 |
itunes | Buy on iTunes | 4 |
amazonmusic | Play on Amazon Music | 5 |
custom (TikTok) | Use My Sound | 6 |
A service that cannot be resolved is skipped silently — the link is still created. Backfill later with fill_missing_deeplinks.
Deeplinks are attached. Each destination gets deeplink_ios and deeplink_android where available, so taps open the native app rather than a browser tab.
Defaults are applied. theme becomes light, preview_type becomes image, display_artist_socials becomes true, and layout becomes 2.
INFO
create_link makes several outbound calls to Spotify and other DSPs, so it is noticeably slower than a plain insert — allow for a multi-second response and set a generous client timeout. Creating many links means running them sequentially or with modest concurrency.
Variations
Playlist link with autoplay
graphql
mutation {
create_link(
artist_id: "3aad8009-..."
domain: "vibe.to"
path: "summer-playlist"
type: "playlist"
spotify_link: "https://open.spotify.com/playlist/37i9dQZF1DXcBWIGoYBM5M"
autoplay_track: "4uLU6hMCjMI75M1A2tKUQC"
) {
success
link { id path autoplay_track }
}
}autoplay_track must be a track that actually appears in the referenced playlist, or the call fails with Autoplay track not found in the playlist. Sending it for a non-playlist link fails with Autoplay track is only available for playlists.
Bio link
graphql
mutation {
create_link(
artist_id: "3aad8009-..."
domain: "vibe.to"
path: "exampleartist"
type: "bio"
spotify_link: "https://open.spotify.com/artist/1uNFoZAHBGtllmzznpCI3s"
display_artist_socials: true
) {
success
link { id path type }
}
}Spotify player preview instead of cover art
graphql
preview_type: "spotify"This attaches a tracks entry with the Spotify preview URL, and the link renders an embedded player instead of a static image.
Checking availability first
path_available tells you whether a domain + path pair is free, without attempting a write.
graphql
mutation CheckPath($domain: String!, $path: String!) {
path_available(domain: $domain, path: $path) {
success
}
}success: true means the path is free. This is a convenience check, not a reservation — the path can still be taken between your check and your create, so handle Path is not available from create_link regardless.
Quick create
quick_create_link builds a link from a source URL in one step, generating a path if you do not supply one. It is aimed at capture flows where a full argument list is not available.
graphql
mutation QuickCreate($source: String!, $domain: String!, $path: String) {
quick_create_link(source: $source, domain: $domain, path: $path) {
success
link_id
artist_id
token
}
}Errors
| Message | Cause |
|---|---|
Invalid type | type was not bio, release, or playlist. |
Invalid spotify link for bio | type: "bio" with a non-artist Spotify URL. |
Invalid spotify link for release | type: "release" without an album or track URL. |
Invalid spotify link for playlist | type: "playlist" without a playlist URL. |
Artist not found or user does not have access to the artist | Wrong artist_id, or your account is not attached to that artist. |
Invalid domain or path | domain is not a valid hostname, or path is empty. |
Path must be 3 at least characters. | path is shorter than three characters. |
Artist does not have access to the domain | Custom domain not assigned to this artist. |
Path is not available | That domain + path already exists. |
Autoplay track is only available for playlists | autoplay_track sent for a non-playlist link. |
Autoplay track not found in the playlist | Track ID is not in the referenced playlist. |
All arrive as INTERNAL_SERVER_ERROR with the message above. See Errors.
WARNING
create_link is not idempotent. If a request times out, query for the domain + path before retrying — the link may already exist.
Next steps
- Edit Link — change a link after creation
- Destinations — add, reorder, and customize destination buttons
- Get Link — read links back