Metadata tags are the values of a tag-type metadata type: the individual genres, moods, instruments and so on that tracks are tagged with.
Tags can be created through the tracks endpoint, which adds missing tags as tracks are uploaded. This endpoint lists tags and lets you maintain them directly: rename them, fix their external IDs or change their order. Its bulk endpoint is the way to load a type’s tags before loading tracks, which for a type with external IDs is the only way short of the object form on a track. Reading is open to every collaborator; creating, updating and deleting need the editor role.
Tags of a type that uses external IDs are addressed by your ID for them. Tags of a type that does not are addressed by name, escaped for a URL: .../metadata_tags/hip%20hop. Names are stored in lower case with surrounding and repeated white space removed, and are matched the same way, so Hip Hop finds hip hop.
Endpoints
Retrieve the tags of a metadata type, in their display order.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
| metadata_type_id |
integer |
ID of the metadata type |
Yes |
Query Parameters
| Name |
Type |
Description |
| page |
integer |
Page number for pagination (default: 1) |
| per_page |
integer |
Records per page, up to 200 (default: 25) |
Response
{
"pagination": {
"total_entries": 15,
"per_page": 25,
"current_page": 1,
"total_pages": 1
},
"metadata_tags": [
{
"id": 101,
"external_id": 101,
"metadata_type_id": 17,
"name": "classical",
"position": 1,
"created_at": "2024-08-13T23:33:54.204-05:00",
"updated_at": "2024-10-10T11:10:20.149-05:00",
"tracks_count": 42,
"url": "https://app.spondulix.ai/api/v1/libraries/2/metadata_types/17/metadata_tags/101",
"tracks_url": "https://app.spondulix.ai/api/v1/libraries/2/metadata_types/17/metadata_tags/101/tracks"
}
]
}
Response Fields
| Field |
Type |
Description |
| pagination |
object |
Contains pagination information |
| metadata_tags |
array |
List of metadata tag objects |
| id |
integer | string |
What addresses the tag: your external ID for it, or its name when the metadata type does not use external IDs |
| external_id |
integer | null |
Your external ID for the tag; null when the metadata type does not use external IDs |
| metadata_type_id |
integer |
ID of the parent metadata type |
| name |
string |
Name of the tag (max 255 chars). Stored lower case with surrounding and repeated whitespace removed. |
| position |
integer |
Display order position |
| created_at |
string |
Timestamp of when the tag was created |
| updated_at |
string |
Timestamp of when the tag was last updated |
| tracks_count |
integer |
Number of tracks that carry the tag |
| url |
string |
URL of the tag |
| tracks_url |
string |
URL of the tag’s tracks |
HTTP Response Codes
| Code |
Description |
200 OK |
Successful request |
404 Not Found |
Invalid library ID or metadata type ID |
Create a metadata tag.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
| metadata_type_id |
integer |
ID of the metadata type |
Yes |
Request Body
Wrap the fields in a metadata_tag key.
| Field |
Type |
Description |
Required |
| name |
string |
Name of the tag (max 255 chars) |
Yes |
| external_id |
integer |
Your identifier for the tag, unique within the metadata type |
Yes, if the metadata type uses external IDs |
| position |
integer |
Display order position. A tag created without one goes last. |
No |
Within a metadata type, names must be unique when the type does not use external IDs, and external IDs must be unique when it does.
{
"metadata_tag": {
"name": "classical",
"external_id": 101,
"position": 1
}
}
Response
Returns the created tag as shown in the list response.
HTTP Response Codes
| Code |
Description |
201 Created |
Successful creation |
403 Forbidden |
Your role does not allow editing |
404 Not Found |
Invalid library ID or metadata type ID |
422 Unprocessable Content |
Invalid request (see response body for details) |
Retrieve a metadata tag.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
| metadata_type_id |
integer |
ID of the metadata type |
Yes |
| id |
integer or string |
External ID of the tag, or its name for a type without external IDs |
Yes |
Response
{
"id": 101,
"external_id": 101,
"metadata_type_id": 17,
"name": "classical",
"position": 1,
"created_at": "2024-08-13T23:33:54.204-05:00",
"updated_at": "2024-10-10T11:10:20.149-05:00",
"tracks_count": 42,
"url": "https://app.spondulix.ai/api/v1/libraries/2/metadata_types/17/metadata_tags/101",
"tracks_url": "https://app.spondulix.ai/api/v1/libraries/2/metadata_types/17/metadata_tags/101/tracks"
}
HTTP Response Codes
| Code |
Description |
200 OK |
Successful request |
404 Not Found |
Invalid library ID, metadata type ID, or tag ID |
Update a metadata tag. PATCH works the same way, and only the fields you send change.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
| metadata_type_id |
integer |
ID of the metadata type |
Yes |
| id |
integer or string |
External ID of the tag, or its name for a type without external IDs |
Yes |
Request Body
| Field |
Type |
Description |
Required |
| name |
string |
Name of the tag |
No |
| external_id |
integer |
New external ID for the tag |
No |
| position |
integer |
Display order position |
No |
Response
Returns the updated tag.
HTTP Response Codes
| Code |
Description |
200 OK |
Successful update |
403 Forbidden |
Your role does not allow editing |
404 Not Found |
Invalid library ID, metadata type ID, or tag ID |
422 Unprocessable Content |
Invalid request (see response body for details) |
Delete a metadata tag, removing it from every track that carried it.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
| metadata_type_id |
integer |
ID of the metadata type |
Yes |
| id |
integer or string |
External ID of the tag, or its name for a type without external IDs |
Yes |
Response
(no response body)
HTTP Response Codes
| Code |
Description |
204 No Content |
Successful deletion |
403 Forbidden |
Your role does not allow editing |
404 Not Found |
Invalid library ID, metadata type ID, or tag ID |
Retrieve the tracks that carry the tag, ordered by title, each as the tracks endpoint gives it, under tracks.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
| metadata_type_id |
integer |
ID of the metadata type |
Yes |
| id |
integer or string |
External ID of the tag, or its name for a type without external IDs |
Yes |
Query Parameters
| Name |
Type |
Description |
| page |
integer |
Page number for pagination (default: 1) |
| per_page |
integer |
Records per page, up to 200 (default: 25) |
Response
A list of tracks with a pagination object, as GET .../tracks returns.
HTTP Response Codes
| Code |
Description |
200 OK |
Successful request |
404 Not Found |
Invalid library ID, metadata type ID, or tag ID |
Create or update up to 1000 tags in one request. A tag is matched to one that exists by external ID when the metadata type uses them and by name when it does not; a tag that matches is updated and one that does not is created. The request is all or nothing: if any tag is invalid, none is saved.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
| metadata_type_id |
integer |
ID of the metadata type |
Yes |
Request Body
| Field |
Type |
Description |
Required |
| metadata_tags |
array |
The tags, each with the fields below |
Yes |
| external_id |
integer |
Your identifier for the tag |
Yes, if the metadata type uses external IDs |
| name |
string |
Name of the tag |
Yes, for a tag that is new |
| position |
integer |
Display order position. Defaults to the tag’s place in the list, counting from 1. |
No |
{
"metadata_tags": [
{ "external_id": 101, "name": "classical" },
{ "external_id": 102, "name": "jazz", "position": 5 }
]
}
Tags after the thousandth are dropped without an error, so send a longer list as several requests. Give each tag a position when you do: the default counts from 1 in every request.
Response
{ "created": 1, "updated": 1 }
HTTP Response Codes
| Code |
Description |
200 OK |
Every tag was saved |
403 Forbidden |
Your role does not allow editing |
404 Not Found |
Invalid library ID or metadata type ID |
422 Unprocessable Content |
metadata_tags is missing or empty, or a tag was invalid and nothing was saved |
A 422 for an invalid tag names each by its place in the list, counting from 0:
{
"message": "1 of 2 tags were invalid; nothing was saved",
"failures": [
{
"index": 1,
"tag": { "name": "" },
"errors": { "name": ["can't be blank"] }
}
]
}
Update the display order of the tags in one request. This endpoint backs the drag-and-drop ordering in the web interface and takes Spondulix’s internal tag IDs, which the API does not return; to reorder tags through the API, set position on each tag with the update endpoint instead.
Path Parameters
| Name |
Type |
Description |
Required |
| library_id |
integer |
ID of the library |
Yes |
| metadata_type_id |
integer |
ID of the metadata type |
Yes |
Request Body
| Field |
Type |
Description |
Required |
| metadata_tag |
array[integer] |
Ordered array of internal tag IDs |
Yes |
Response
(no response body)
HTTP Response Codes
| Code |
Description |
200 OK |
Successful update |
403 Forbidden |
Your role does not allow editing |
404 Not Found |
Invalid library ID, metadata type ID, or tag ID |