> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pictory.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Search Music Tracks

> Search for music tracks based on various filters including genres, moods, instruments, purposes, and duration

## Overview

Search through Pictory's music library to find tracks that match your specific criteria. Filter by multiple attributes including genre groups, genres, moods, instruments, purposes, duration, and search queries. Results include streaming URLs, metadata, and comprehensive categorization data.

<Note>
  You need a valid API key to use this endpoint. Get your API key from the [API Access page](https://app.pictory.ai/api-access) in your Pictory dashboard.
</Note>

***

## API Endpoint

```http theme={null}
POST https://api.pictory.ai/pictoryapis/v1/music/search
```

***

## Request Parameters

### Headers

<ParamField header="Authorization" type="string" required>
  API key for authentication (starts with `pictai_`)

  ```
  Authorization: YOUR_API_KEY
  ```
</ParamField>

### Body Parameters

<ParamField body="page" type="integer" default="1">
  Page number for pagination (must be ≥ 1)
</ParamField>

<ParamField body="pageSize" type="integer" default="100">
  Number of results per page (must be between 20 and 100)
</ParamField>

<ParamField body="sort" type="string" default="latest">
  Sort order for results

  **Options:**

  * `latest` - Sort by most recently added tracks
  * `shuffle` - Randomize the order of results
  * `featured` - Sort by featured/curated tracks
</ParamField>

<ParamField body="query" type="string">
  Search query to filter tracks by keywords in title or description
</ParamField>

<ParamField body="genreGroup" type="array of strings">
  Filter by genre groups (e.g., \["Rock", "Electronic"]). Use the [Get Music Genre Groups](/api-reference/music-search/get-music-genre-groups) endpoint to retrieve valid values.
</ParamField>

<ParamField body="notGenreGroup" type="array of strings">
  Exclude specific genre groups from results
</ParamField>

<ParamField body="genre" type="array of strings">
  Filter by specific genres (e.g., \["Indie Rock", "Techno"]). Use the [Get Music Genres](/api-reference/music-search/get-music-genres) endpoint to retrieve valid values.
</ParamField>

<ParamField body="notGenre" type="array of strings">
  Exclude specific genres from results
</ParamField>

<ParamField body="mood" type="array of strings">
  Filter by moods (e.g., \["Happy / Bright", "Energetic / Lively"]). Use the [Get Music Moods](/api-reference/music-search/get-music-moods) endpoint to retrieve valid values.
</ParamField>

<ParamField body="notMood" type="array of strings">
  Exclude specific moods from results
</ParamField>

<ParamField body="instrument" type="array of strings">
  Filter by instruments (e.g., \["Piano", "Guitar - Acoustic"]). Use the [Get Music Instruments](/api-reference/music-search/get-music-instruments) endpoint to retrieve valid values.
</ParamField>

<ParamField body="notInstrument" type="array of strings">
  Exclude specific instruments from results
</ParamField>

<ParamField body="purpose" type="array of strings">
  Filter by purposes (e.g., \["Corporate / Business", "Wedding"]). Use the [Get Music Purposes](/api-reference/music-search/get-music-purposes) endpoint to retrieve valid values.
</ParamField>

<ParamField body="notPurpose" type="array of strings">
  Exclude specific purposes from results
</ParamField>

<ParamField body="minDuration" type="integer">
  Minimum track duration in seconds
</ParamField>

<ParamField body="maxDuration" type="integer">
  Maximum track duration in seconds
</ParamField>

***

## Response

<ResponseField name="items" type="array of objects">
  Array of music track objects matching the search criteria

  <Expandable title="track item">
    <ResponseField name="id" type="integer">
      Unique identifier for the music track
    </ResponseField>

    <ResponseField name="title" type="string">
      Title of the music track
    </ResponseField>

    <ResponseField name="audioUrl" type="string">
      Direct streaming URL for the audio track
    </ResponseField>

    <ResponseField name="duration" type="integer">
      Track duration in seconds
    </ResponseField>

    <ResponseField name="genres" type="array of strings">
      List of genres associated with the track
    </ResponseField>

    <ResponseField name="instruments" type="array of strings">
      List of instruments featured in the track
    </ResponseField>

    <ResponseField name="moods" type="array of strings">
      List of moods/emotions conveyed by the track
    </ResponseField>

    <ResponseField name="purposes" type="array of strings">
      List of suggested use cases or purposes for the track
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="totalItems" type="integer">
  Total number of tracks matching the search criteria across all pages
</ResponseField>

<ResponseField name="totalPages" type="integer">
  Total number of pages available for the search results
</ResponseField>

<ResponseField name="currentPage" type="integer">
  Current page number in the result set
</ResponseField>

## Response Examples

<ResponseExample>
  ```json 200 - Success theme={null}
  {
    "items": [
      {
        "id": 279,
        "title": "Bio Journey",
        "audioUrl": "https://tracks.melod.ie/track_versions/570/MEL142_06_1_Bio_Journey_%28Full%29_David_Godfrey_stream.mp3?1736295063",
        "duration": 161,
        "genres": ["Downtempo"],
        "instruments": [
          "Bass - Electric",
          "Bass - Synth",
          "Guitar - Electric",
          "Keyboard",
          "Percussion",
          "Synth"
        ],
        "moods": [
          "Calm / Serene",
          "Ethereal / Airy",
          "Feel Good",
          "Gentle / Soft",
          "Happy / Bright",
          "Hopeful / Optimistic",
          "Quirky / Kitsch",
          "Smooth / Flowing",
          "Sweet / Warm",
          "Upbeat / Cheerful"
        ],
        "purposes": [
          "Atmospheric",
          "Corporate / Business",
          "Mystery / Tension",
          "Real Estate",
          "Simple / Minimal",
          "Technology",
          "Time Lapse"
        ]
      },
      {
        "id": 165,
        "title": "Dusty Road Trip",
        "audioUrl": "https://tracks.melod.ie/track_versions/316/MEL119_01_1_Dusty_Road_Trip_%28Full%29_Marcos_H_Bolanos_stream.mp3?1725242063",
        "duration": 147,
        "genres": ["Country Rock", "Electric Blues"],
        "instruments": [
          "Bass - Electric",
          "Drum Kit",
          "Guitar - Acoustic",
          "Guitar - Electric",
          "Harmonica",
          "Shaker"
        ],
        "moods": [
          "Celebration",
          "Confident",
          "Energetic / Lively",
          "Exciting / Rousing",
          "Feel Good",
          "Fun",
          "Grooving",
          "Happy / Bright",
          "Hopeful / Optimistic",
          "Joyful",
          "Playful / Whimsical",
          "Punchy",
          "Rowdy / Boisterous",
          "Sweet / Warm",
          "Upbeat / Cheerful"
        ],
        "purposes": [
          "Adventure",
          "Nature / Beauty",
          "Road Trip",
          "Western / Cowboy"
        ]
      }
    ],
    "totalItems": 1541,
    "totalPages": 78,
    "currentPage": 1
  }
  ```

  ```json 400 - Bad Request theme={null}
  {
    "code": "INVALID_REQUEST_BODY",
    "message": "Request body validation failed.",
    "fields": [
      {
        "name": "pageSize",
        "errors": "pageSize must be greater than or equal to 20"
      }
    ]
  }
  ```

  ```json 401 - Unauthorized theme={null}
  {
    "message": "Unauthorized"
  }
  ```
</ResponseExample>

***

## Code Examples

<Tip>
  Replace `YOUR_API_KEY` with your actual API key that starts with `pictai_`
</Tip>

<CodeGroup>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.pictory.ai/pictoryapis/v1/music/search \
    --header 'Authorization: YOUR_API_KEY' \
    --header 'Content-Type: application/json' \
    --header 'accept: application/json' \
    --data '{
      "page": 1,
      "pageSize": 20,
      "query": "upbeat",
      "mood": ["Happy / Bright", "Energetic / Lively"],
      "purpose": ["Corporate / Business"]
    }' | python -m json.tool
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.pictory.ai/pictoryapis/v1/music/search"
  headers = {
      "Authorization": "YOUR_API_KEY",
      "Content-Type": "application/json",
      "accept": "application/json"
  }
  payload = {
      "page": 1,
      "pageSize": 20,
      "query": "upbeat",
      "mood": ["Happy / Bright", "Energetic / Lively"],
      "purpose": ["Corporate / Business"]
  }

  response = requests.post(url, json=payload, headers=headers)
  data = response.json()

  # Print results
  print(f"Found {data['totalItems']} tracks across {data['totalPages']} pages")
  for track in data['items']:
      print(f"\nTitle: {track['title']}")
      print(f"Duration: {track['duration']} seconds")
      print(f"Genres: {', '.join(track['genres'])}")
      print(f"Audio URL: {track['audioUrl']}")
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    'https://api.pictory.ai/pictoryapis/v1/music/search',
    {
      method: 'POST',
      headers: {
        'Authorization': 'YOUR_API_KEY',
        'Content-Type': 'application/json',
        'accept': 'application/json'
      },
      body: JSON.stringify({
        page: 1,
        pageSize: 20,
        query: 'upbeat',
        mood: ['Happy / Bright', 'Energetic / Lively'],
        purpose: ['Corporate / Business']
      })
    }
  );

  const data = await response.json();

  // Print results
  console.log(`Found ${data.totalItems} tracks across ${data.totalPages} pages`);
  data.items.forEach(track => {
    console.log(`\nTitle: ${track.title}`);
    console.log(`Duration: ${track.duration} seconds`);
    console.log(`Genres: ${track.genres.join(', ')}`);
    console.log(`Audio URL: ${track.audioUrl}`);
  });
  ```
</CodeGroup>

***

## Usage Notes

<Tip>
  Use the negation filters (`notGenre`, `notMood`, `notInstrument`, `notPurpose`) to exclude specific attributes and refine your search results. This is particularly useful for finding tracks that match a mood but exclude certain instruments or genres.
</Tip>

<Note>
  **Pagination Requirements**: The `pageSize` parameter must be between 20 and 100. If you need fewer results, simply use the first N items from the response array.
</Note>

<Note>
  **Filter Validation**: All filter values (genres, moods, instruments, purposes) are case-sensitive and must match exactly as returned by their respective list endpoints. Use the dedicated GET endpoints to retrieve valid filter values before searching.
</Note>

## Common Use Cases

### 1. Search by Keyword

Find tracks matching a specific search term:

```python theme={null}
import requests

url = "https://api.pictory.ai/pictoryapis/v1/music/search"
headers = {
    "Authorization": "YOUR_API_KEY",
    "Content-Type": "application/json"
}

# Search for "corporate" themed music
payload = {
    "page": 1,
    "pageSize": 20,
    "query": "corporate"
}

response = requests.post(url, json=payload, headers=headers)
tracks = response.json()

print(f"Found {tracks['totalItems']} corporate tracks")
```

### 2. Filter by Multiple Criteria

Combine multiple filters for precise results:

```javascript theme={null}
const searchTracks = async (filters) => {
  const response = await fetch(
    'https://api.pictory.ai/pictoryapis/v1/music/search',
    {
      method: 'POST',
      headers: {
        'Authorization': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        page: 1,
        pageSize: 20,
        genre: ['Indie Rock', 'Pop Rock'],
        mood: ['Energetic / Lively', 'Happy / Bright'],
        instrument: ['Guitar - Electric', 'Drum Kit'],
        purpose: ['Corporate / Business', 'Branding / Identity'],
        minDuration: 60,
        maxDuration: 180
      })
    }
  );

  const data = await response.json();
  return data.items;
};

// Get energetic rock tracks suitable for corporate use
const tracks = await searchTracks();
console.log(`Found ${tracks.length} matching tracks`);
```

### 3. Exclude Unwanted Attributes

Use negation filters to refine results:

```python theme={null}
# Find upbeat music WITHOUT specific moods or instruments
payload = {
    "page": 1,
    "pageSize": 20,
    "mood": ["Upbeat / Cheerful", "Energetic / Lively"],
    "notMood": ["Dark / Brooding", "Sad / Melancholic"],
    "notInstrument": ["Violin / Viola", "Cello"],
    "purpose": ["Corporate / Business"]
}

response = requests.post(
    "https://api.pictory.ai/pictoryapis/v1/music/search",
    json=payload,
    headers={"Authorization": "YOUR_API_KEY", "Content-Type": "application/json"}
)

tracks = response.json()
print(f"Found {tracks['totalItems']} upbeat corporate tracks without strings")
```

### 4. Duration-Based Search

Find tracks within a specific duration range:

```python theme={null}
def find_tracks_by_duration(min_sec, max_sec, purpose=None):
    """
    Find music tracks within a specific duration range
    """
    payload = {
        "page": 1,
        "pageSize": 50,
        "minDuration": min_sec,
        "maxDuration": max_sec
    }

    if purpose:
        payload["purpose"] = [purpose]

    response = requests.post(
        "https://api.pictory.ai/pictoryapis/v1/music/search",
        json=payload,
        headers={
            "Authorization": "YOUR_API_KEY",
            "Content-Type": "application/json"
        }
    )

    return response.json()

# Find short corporate tracks (30-60 seconds)
short_tracks = find_tracks_by_duration(30, 60, "Corporate / Business")
print(f"Found {short_tracks['totalItems']} tracks between 30-60 seconds")

# Find longer background tracks (3-5 minutes)
long_tracks = find_tracks_by_duration(180, 300)
print(f"Found {long_tracks['totalItems']} tracks between 3-5 minutes")
```

### 5. Paginate Through Results

Retrieve all pages of search results:

```javascript theme={null}
async function getAllTracks(searchCriteria) {
  let allTracks = [];
  let currentPage = 1;
  let totalPages = 1;

  while (currentPage <= totalPages) {
    const response = await fetch(
      'https://api.pictory.ai/pictoryapis/v1/music/search',
      {
        method: 'POST',
        headers: {
          'Authorization': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          ...searchCriteria,
          page: currentPage,
          pageSize: 100 // Maximum page size
        })
      }
    );

    const data = await response.json();
    allTracks = allTracks.concat(data.items);
    totalPages = data.totalPages;
    currentPage++;

    console.log(`Retrieved page ${currentPage - 1} of ${totalPages}`);
  }

  return allTracks;
}

// Get all piano tracks
const allPianoTracks = await getAllTracks({
  instrument: ['Piano']
});
console.log(`Total piano tracks: ${allPianoTracks.length}`);
```

### 6. Sort and Filter Combined

Use sorting with filters for optimal results:

```python theme={null}
# Get latest upbeat corporate tracks
payload = {
    "page": 1,
    "pageSize": 20,
    "sort": "latest",
    "mood": ["Upbeat / Cheerful", "Energetic / Lively"],
    "purpose": ["Corporate / Business", "Branding / Identity"]
}

response = requests.post(
    "https://api.pictory.ai/pictoryapis/v1/music/search",
    json=payload,
    headers={
        "Authorization": "YOUR_API_KEY",
        "Content-Type": "application/json"
    }
)

latest_tracks = response.json()

# Get featured tracks for variety
payload["sort"] = "featured"
response = requests.post(
    "https://api.pictory.ai/pictoryapis/v1/music/search",
    json=payload,
    headers={
        "Authorization": "YOUR_API_KEY",
        "Content-Type": "application/json"
    }
)

featured_tracks = response.json()
```

### 7. Build a Smart Music Recommender

Create recommendations based on video content:

```python theme={null}
def recommend_music_for_video(video_keywords, video_duration, video_type):
    """
    Recommend music based on video characteristics
    """
    # Map video type to purpose
    purpose_mapping = {
        "corporate": ["Corporate / Business", "Branding / Identity"],
        "wedding": ["Wedding", "Romantic Comedy"],
        "travel": ["Adventure", "Road Trip", "Nature / Beauty"],
        "tech": ["Technology", "Futuristic"],
        "kids": ["Children / Preschool", "Educational"]
    }

    # Determine mood from keywords
    mood_mapping = {
        "happy": ["Happy / Bright", "Joyful", "Upbeat / Cheerful"],
        "calm": ["Calm / Serene", "Gentle / Soft"],
        "energetic": ["Energetic / Lively", "Exciting / Rousing"],
        "dramatic": ["Dramatic", "Intense / Hard"]
    }

    purposes = purpose_mapping.get(video_type, [])
    moods = []
    for keyword in video_keywords:
        if keyword in mood_mapping:
            moods.extend(mood_mapping[keyword])

    # Search with calculated criteria
    payload = {
        "page": 1,
        "pageSize": 20,
        "sort": "featured",
        "purpose": purposes,
        "mood": moods,
        "minDuration": int(video_duration * 0.8),  # At least 80% of video duration
        "maxDuration": int(video_duration * 1.2)   # At most 120% of video duration
    }

    response = requests.post(
        "https://api.pictory.ai/pictoryapis/v1/music/search",
        json=payload,
        headers={
            "Authorization": "YOUR_API_KEY",
            "Content-Type": "application/json"
        }
    )

    return response.json()

# Example: Find music for 90-second corporate video with happy theme
recommendations = recommend_music_for_video(
    video_keywords=["happy", "energetic"],
    video_duration=90,
    video_type="corporate"
)

print(f"Recommended {len(recommendations['items'])} tracks")
for track in recommendations['items'][:5]:
    print(f"- {track['title']} ({track['duration']}s)")
```

### 8. Genre Group Exploration

Search by high-level genre groups and drill down:

```javascript theme={null}
async function exploreGenreGroup(genreGroup) {
  // First, search by genre group
  const groupResponse = await fetch(
    'https://api.pictory.ai/pictoryapis/v1/music/search',
    {
      method: 'POST',
      headers: {
        'Authorization': 'YOUR_API_KEY',
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        page: 1,
        pageSize: 20,
        genreGroup: [genreGroup],
        sort: 'featured'
      })
    }
  );

  const groupTracks = await groupResponse.json();

  // Analyze genres within this group
  const genresFound = new Set();
  groupTracks.items.forEach(track => {
    track.genres.forEach(genre => genresFound.add(genre));
  });

  console.log(`Genre Group: ${genreGroup}`);
  console.log(`Total tracks: ${groupTracks.totalItems}`);
  console.log(`Specific genres found: ${Array.from(genresFound).join(', ')}`);

  return {
    totalTracks: groupTracks.totalItems,
    genres: Array.from(genresFound),
    sampleTracks: groupTracks.items
  };
}

// Explore Electronic music
const electronicMusic = await exploreGenreGroup('Electronic');
```
