API

Documentation

Version 1.0

Pagination

The AutoTechJobs API uses cursor-based pagination for list endpoints to efficiently navigate through large result sets. This page explains how to use pagination in your API requests.

Overview

All API endpoints that return lists of objects (such as jobs, applications, candidates, etc.) support pagination. By default, these endpoints return a limited number of results per page to ensure optimal performance.

The response includes pagination metadata that allows you to navigate to the next or previous page of results. This metadata is included in the meta object of the response.

Pagination Parameters

When making requests to list endpoints, you can include the following query parameters to control pagination:

ParameterTypeDefaultDescription
limitinteger20Number of items to return per page (max 100)
cursorstringnullCursor for pagination (obtained from previous response)

Response Format

Paginated responses follow a consistent format that includes both the data and pagination metadata:

{
  "data": [
    // Array of objects (jobs, applications, etc.)
  ],
  "meta": {
    "pagination": {
      "total": 157,       // Total number of items available
      "limit": 20,        // Number of items per page
      "has_more": true,   // Whether there are more items to fetch
      "next_cursor": "cursor_abc123",  // Cursor for the next page
      "prev_cursor": null // Cursor for the previous page (null if first page)
    }
  }
}

Pagination Metadata

FieldTypeDescription
totalintegerThe total number of items available
limitintegerThe number of items per page
has_morebooleanWhether there are more items to fetch
next_cursorstringCursor for the next page (null if no more pages)
prev_cursorstringCursor for the previous page (null if first page)

Example Usage

Initial Request

// Request
GET https://api.autotechjobs.co.uk/v1/jobs?limit=10

// Response
{
  "data": [
    {
      "id": "job_123",
      "title": "Senior React Developer",
      "company": "Tech Innovations Ltd",
      // ... other job fields
    },
    // ... 9 more jobs
  ],
  "meta": {
    "pagination": {
      "total": 157,
      "limit": 10,
      "has_more": true,
      "next_cursor": "cursor_abc123",
      "prev_cursor": null
    }
  }
}

Fetching the Next Page

// Request
GET https://api.autotechjobs.co.uk/v1/jobs?limit=10&cursor=cursor_abc123

// Response
{
  "data": [
    {
      "id": "job_456",
      "title": "DevOps Engineer",
      "company": "Cloud Solutions Inc",
      // ... other job fields
    },
    // ... 9 more jobs
  ],
  "meta": {
    "pagination": {
      "total": 157,
      "limit": 10,
      "has_more": true,
      "next_cursor": "cursor_def456",
      "prev_cursor": "cursor_prev789"
    }
  }
}

Code Examples

Fetching All Pages (JavaScript)

async function fetchAllJobs() {
  const allJobs = [];
  let hasMore = true;
  let cursor = null;
  
  while (hasMore) {
    // Construct the URL with pagination parameters
    const url = new URL('https://api.autotechjobs.co.uk/v1/jobs');
    url.searchParams.append('limit', '50');
    if (cursor) {
      url.searchParams.append('cursor', cursor);
    }
    
    // Make the request
    const response = await fetch(url.toString(), {
      headers: {
        'Authorization': 'Bearer YOUR_API_KEY'
      }
    });
    
    const data = await response.json();
    
    // Add the jobs to our collection
    allJobs.push(...data.data);
    
    // Check if there are more pages
    hasMore = data.meta.pagination.has_more;
    cursor = data.meta.pagination.next_cursor;
    
    // Optional: Add a delay to avoid hitting rate limits
    if (hasMore) {
      await new Promise(resolve => setTimeout(resolve, 100));
    }
  }
  
  return allJobs;
}

Implementing a Paginated List (React)

import React, { useState, useEffect } from 'react';

function JobsList() {
  const [jobs, setJobs] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const [pagination, setPagination] = useState({
    hasMore: false,
    nextCursor: null,
    prevCursor: null
  });
  
  const fetchJobs = async (cursor = null) => {
    setLoading(true);
    setError(null);
    
    try {
      const url = new URL('https://api.autotechjobs.co.uk/v1/jobs');
      url.searchParams.append('limit', '20');
      if (cursor) {
        url.searchParams.append('cursor', cursor);
      }
      
      const response = await fetch(url.toString(), {
        headers: {
          'Authorization': 'Bearer YOUR_API_KEY'
        }
      });
      
      if (!response.ok) {
        throw new Error('Failed to fetch jobs');
      }
      
      const data = await response.json();
      
      setJobs(data.data);
      setPagination({
        hasMore: data.meta.pagination.has_more,
        nextCursor: data.meta.pagination.next_cursor,
        prevCursor: data.meta.pagination.prev_cursor
      });
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };
  
  useEffect(() => {
    fetchJobs();
  }, []);
  
  const handleNextPage = () => {
    if (pagination.hasMore && pagination.nextCursor) {
      fetchJobs(pagination.nextCursor);
    }
  };
  
  const handlePrevPage = () => {
    if (pagination.prevCursor) {
      fetchJobs(pagination.prevCursor);
    }
  };
  
  if (loading) return <p>Loading jobs...</p>;
  if (error) return <p>Error: {error}</p>;
  
  return (
    <div>
      <h2>Jobs List</h2>
      
      <div className="jobs-list">
        {jobs.map(job => (
          <div key={job.id} className="job-card">
            <h3>{job.title}</h3>
            <p>{job.company}</p>
            {/* Render other job details */}
          </div>
        ))}
      </div>
      
      <div className="pagination-controls">
        <button 
          onClick={handlePrevPage} 
          disabled={!pagination.prevCursor}
        >
          Previous Page
        </button>
        
        <button 
          onClick={handleNextPage} 
          disabled={!pagination.hasMore}
        >
          Next Page
        </button>
      </div>
    </div>
  );
}

Best Practices

  • Use cursor-based pagination: Always use the cursor parameter for pagination rather than calculating offsets manually. Cursor-based pagination is more efficient and reliable for large datasets.
  • Set appropriate limits: Choose a limit that balances between reducing the number of API calls and not retrieving too much data at once. The default limit of 20 is a good starting point.
  • Cache results: Consider caching paginated results to improve performance and reduce API calls.
  • Implement infinite scrolling: For better user experience, consider implementing infinite scrolling in your UI, loading more data as the user scrolls down.
  • Handle edge cases: Be prepared to handle cases where the dataset changes between page requests, which might result in duplicated or missing items.