# Fetching Content Lists

Fetch lists of workouts, plans, or exercises with optional filtering.

**Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| category | String | Filter by category. **Required for plans** in Flutter, Swift, and Kotlin SDKs. Optional for workouts and exercises. |
| bodyParts | [BodyPart] | Filter by targeted body parts (optional) |
| include_kinestex | Bool | Include KinesteX workout library in results (default: true) |
| limit | Int | Number of results to return (default: 10) |
| lang | String | Language code (default: "en") |
| lastDocId | String | For pagination (optional) |
| translation_languages | String | Filter by available translations. Comma-separated language codes (e.g. "es,fr") or repeated query parameters (optional, REST API only) |

**Fetch Workouts**

_Swift (iOS)_
```swift
// Fetch workouts with optional filters
Task {
    let result = await kinestex.fetchWorkouts(
        category: "Fitness",  // or "Rehabilitation"
        limit: 10
    )

    switch result {
    case .success(let response):
        let workouts = response.workouts
        print("Fetched \(workouts.count) workouts")

        for workout in workouts {
            print("- \(workout.title): \(workout.totalMinutes ?? 0) mins")
        }

        // Store lastDocId for pagination
        let nextPageId = response.lastDocId

    case .failure(let error):
        print("Error: \(error.localizedDescription)")
    }
}
```

_Kotlin (Android)_
```kotlin
// Fetch workouts using coroutines
lifecycleScope.launch {
    val result = withContext(Dispatchers.IO) {
        KinesteXSDK.api.fetchAPIContentData(
            contentType = ContentType.WORKOUT,
            category = "Fitness",  // or "Rehabilitation"
            limit = 10
        )
    }

    when (result) {
        is APIContentResult.Workouts -> {
            val workouts = result.workouts
            Log.d("API", "Fetched ${workouts.size} workouts")

            workouts.forEach { workout ->
                Log.d("API", "- ${workout.title}")
            }

            // Store lastDocId for pagination
            val nextPageId = result.lastDocId
        }
        is APIContentResult.Error -> {
            Log.e("API", "Error: ${result.message}")
        }
        else -> {
            Log.w("API", "Unexpected result type")
        }
    }
}
```

_Flutter_
```dart
// Fetch workouts
Future<void> fetchWorkouts() async {
  final result = await KinesteXAIFramework.apiService.fetchContent(
    contentType: ContentType.workout,
    category: "Fitness",  // or "Rehabilitation"
    limit: 10,
  );

  switch (result) {
    case WorkoutsResult(:final response):
      final workouts = response.workouts;
      print('Fetched ${workouts.length} workouts');

      for (final workout in workouts) {
        print('- ${workout.title}');
      }

      // Store lastDocId for pagination
      final nextPageId = response.lastDocId;

    case ErrorResult(:final message):
      print('Error: $message');

    default:
      print('Unexpected result type');
  }
}
```

_React Native_
```jsx
// Fetch workouts using fetch API
const fetchWorkouts = async (
  category?: string,
  limit: number = 10
): Promise<WorkoutModel[]> => {
  const params = new URLSearchParams({
    limit: String(limit),
  });

  if (category) {
    params.append('category', category);
  }

  const response = await fetch(
    `${BASE_URL}/workouts?${params}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error(`API Error: ${response.status}`);
  }

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

// Usage
const workouts = await fetchWorkouts('Fitness', 10);
console.log(`Fetched ${workouts.length} workouts`);
```

_HTML / JavaScript_
```html
// Fetch workouts using fetch API
async function fetchWorkouts(category, limit = 10) {
  const params = new URLSearchParams({ limit: String(limit) });

  if (category) {
    params.append('category', category);
  }

  const response = await fetch(
    `${BASE_URL}/workouts?${params}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error(`API Error: ${response.status}`);
  }

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

// Usage
fetchWorkouts('Fitness', 10)
  .then(workouts => console.log(`Fetched ${workouts.length} workouts`))
  .catch(error => console.error('Error:', error));
```

_React (TypeScript)_
```tsx
// Fetch workouts with TypeScript
interface WorkoutsResponse {
  workouts: WorkoutModel[];
  lastDocId?: string;
}

const fetchWorkouts = async (
  category?: string,
  limit: number = 10
): Promise<WorkoutsResponse> => {
  const params = new URLSearchParams({
    limit: String(limit),
  });

  if (category) {
    params.append('category', category);
  }

  const response = await fetch(
    `${BASE_URL}/workouts?${params}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error(`API Error: ${response.status}`);
  }

  return response.json();
};

// Usage
const { workouts, lastDocId } = await fetchWorkouts('Fitness', 10);
console.log(`Fetched ${workouts.length} workouts`);
```

**Fetch Plans**

_Swift (iOS)_
```swift
// Fetch workout plans
Task {
    let result = await kinestex.fetchPlans(
        category: "Strength",  // Rehabilitation, Weight Management, Cardio, Strength
        limit: 5
    )

    switch result {
    case .success(let response):
        let plans = response.plans
        print("Fetched \(plans.count) plans")

    case .failure(let error):
        print("Error: \(error.localizedDescription)")
    }
}
```

_Kotlin (Android)_
```kotlin
// Fetch workout plans
// IMPORTANT: Always provide 'category' when fetching plans.
lifecycleScope.launch {
    val result = withContext(Dispatchers.IO) {
        KinesteXSDK.api.fetchAPIContentData(
            contentType = ContentType.PLAN,
            category = "Strength",  // Required: Rehabilitation, Weight Management, Cardio, Strength
            limit = 5
        )
    }

    when (result) {
        is APIContentResult.Plans -> {
            val plans = result.plans
            Log.d("API", "Fetched ${plans.size} plans")
        }
        is APIContentResult.Error -> {
            Log.e("API", "Error: ${result.message}")
        }
        else -> {}
    }
}
```

_Flutter_
```dart
// Fetch workout plans
// IMPORTANT: Always provide 'category' when fetching plans.
// If category is null, the SDK may interpret the response as a single PlanResult
// instead of PlansResult (list).
Future<void> fetchPlans() async {
  final result = await KinesteXAIFramework.apiService.fetchContent(
    contentType: ContentType.plan,
    category: "Strength",  // Required: Rehabilitation, Weight Management, Cardio, Strength
    limit: 5,
  );

  switch (result) {
    case PlansResult(:final response):
      final plans = response.plans;
      print('Fetched ${plans.length} plans');

    case ErrorResult(:final message):
      print('Error: $message');

    default:
      break;
  }
}
```

_React Native_
```jsx
// Fetch workout plans
const fetchPlans = async (
  category?: string,
  limit: number = 5
): Promise<PlanModel[]> => {
  const params = new URLSearchParams({ limit: String(limit) });

  if (category) {
    params.append('category', category);
  }

  const response = await fetch(
    `${BASE_URL}/plans?${params}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error(`API Error: ${response.status}`);
  }

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

// Usage - Plan categories: Rehabilitation, Weight Management, Cardio, Strength
const plans = await fetchPlans('Strength', 5);
```

_HTML / JavaScript_
```html
// Fetch workout plans
async function fetchPlans(category, limit = 5) {
  const params = new URLSearchParams({ limit: String(limit) });

  if (category) {
    params.append('category', category);
  }

  const response = await fetch(
    `${BASE_URL}/plans?${params}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error(`API Error: ${response.status}`);
  }

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

// Usage - Plan categories: Rehabilitation, Weight Management, Cardio, Strength
fetchPlans('Strength', 5).then(plans => console.log(plans));
```

_React (TypeScript)_
```tsx
// Fetch workout plans
interface PlansResponse {
  plans: PlanModel[];
  lastDocId?: string;
}

const fetchPlans = async (
  category?: string,
  limit: number = 5
): Promise<PlansResponse> => {
  const params = new URLSearchParams({ limit: String(limit) });

  if (category) {
    params.append('category', category);
  }

  const response = await fetch(
    `${BASE_URL}/plans?${params}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error(`API Error: ${response.status}`);
  }

  return response.json();
};

// Usage - Plan categories: Rehabilitation, Weight Management, Cardio, Strength
const { plans } = await fetchPlans('Strength', 5);
```

**Fetch Exercises**

_Swift (iOS)_
```swift
// Fetch exercises filtered by body parts
Task {
    let result = await kinestex.fetchExercises(
        bodyParts: [.abs, .glutes],
        limit: 10
    )

    switch result {
    case .success(let response):
        let exercises = response.exercises
        print("Fetched \(exercises.count) exercises")

        for exercise in exercises {
            print("- \(exercise.title): \(exercise.bodyParts.joined(separator: ", "))")
        }

    case .failure(let error):
        print("Error: \(error.localizedDescription)")
    }
}
```

_Kotlin (Android)_
```kotlin
// Fetch exercises filtered by body parts
lifecycleScope.launch {
    val result = withContext(Dispatchers.IO) {
        KinesteXSDK.api.fetchAPIContentData(
            contentType = ContentType.EXERCISE,
            bodyParts = listOf(BodyPart.ABS, BodyPart.GLUTES),
            limit = 10
        )
    }

    when (result) {
        is APIContentResult.Exercises -> {
            val exercises = result.exercises
            Log.d("API", "Fetched ${exercises.size} exercises")

            exercises.forEach { exercise ->
                Log.d("API", "- ${exercise.title}")
            }
        }
        is APIContentResult.Error -> {
            Log.e("API", "Error: ${result.message}")
        }
        else -> {}
    }
}
```

_Flutter_
```dart
// Fetch exercises filtered by body parts
Future<void> fetchExercises() async {
  final result = await KinesteXAIFramework.apiService.fetchContent(
    contentType: ContentType.exercise,
    bodyParts: [BodyPart.abs, BodyPart.glutes],
    limit: 10,
  );

  switch (result) {
    case ExercisesResult(:final response):
      final exercises = response.exercises;
      print('Fetched ${exercises.length} exercises');

      for (final exercise in exercises) {
        print('- ${exercise.title}');
      }

    case ErrorResult(:final message):
      print('Error: $message');

    default:
      break;
  }
}
```

_React Native_
```jsx
// Fetch exercises filtered by body parts
const fetchExercises = async (
  bodyParts?: string[],
  limit: number = 10
): Promise<ExerciseModel[]> => {
  const params = new URLSearchParams({ limit: String(limit) });

  if (bodyParts && bodyParts.length > 0) {
    params.append('body_parts', bodyParts.join(','));
  }

  const response = await fetch(
    `${BASE_URL}/exercises?${params}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error(`API Error: ${response.status}`);
  }

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

// Usage
const exercises = await fetchExercises(['Abs', 'Glutes'], 10);
```

_HTML / JavaScript_
```html
// Fetch exercises filtered by body parts
async function fetchExercises(bodyParts, limit = 10) {
  const params = new URLSearchParams({ limit: String(limit) });

  if (bodyParts && bodyParts.length > 0) {
    params.append('body_parts', bodyParts.join(','));
  }

  const response = await fetch(
    `${BASE_URL}/exercises?${params}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error(`API Error: ${response.status}`);
  }

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

// Usage
fetchExercises(['Abs', 'Glutes'], 10).then(exercises => console.log(exercises));
```

_React (TypeScript)_
```tsx
// Fetch exercises filtered by body parts
interface ExercisesResponse {
  exercises: ExerciseModel[];
  lastDocId?: string;
}

const fetchExercises = async (
  bodyParts?: string[],
  limit: number = 10
): Promise<ExercisesResponse> => {
  const params = new URLSearchParams({ limit: String(limit) });

  if (bodyParts && bodyParts.length > 0) {
    params.append('body_parts', bodyParts.join(','));
  }

  const response = await fetch(
    `${BASE_URL}/exercises?${params}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error(`API Error: ${response.status}`);
  }

  return response.json();
};

// Usage
const { exercises } = await fetchExercises(['Abs', 'Glutes'], 10);
```

---
Source: https://kinestex.com/docs/content-api/content-api-lists · Index: https://kinestex.com/llms.txt
