CROWDMANAGERCROWDMANAGER

Ticketing API

  1. Users
  2. Tickets
  3. Merchandise
  4. Members
  5. Users Permissions

Important Notes

Authentication: All endpoints require Basic Authentication using the format Authorization: Basic {your_access_token}. See Security for more details.

Required Parameters: All endpoints require date_init and date_end parameters (Unix timestamps in seconds). The date range cannot exceed 3 years.

Pagination: Pages are 0-based (first page is page=0). The API returns responses in the format:

{
  "count": 1000,
  "page": 0,
  "items": [...]
}

API Usage Best Practices for Paginated Requests

To ensure optimal performance and avoid overloading the server, we strongly recommend that developers:

1) Avoid firing all paginated requests simultaneously. Doing so can lead to rate limiting, timeouts, or even temporary bans depending on server constraints.

2) Implement synchronous requests with controlled delays. This ensures a smooth data retrieval process while maintaining server stability.

3) Consider using a timeout or retry mechanism. This is particularly useful in case of transient network issues or server delays.

4) Schedule API Calls Outside Business Hours For optimal server performance and minimal disruption, execute the data collection process during non-peak hours, such as late nights or early mornings.

5) Always include required date parameters. All endpoints require date_init and date_end parameters. Ensure your date range does not exceed 3 years.

Example Python Implementation

Below is an example of how to fetch paginated results synchronously using Python:

import requests
import time
from datetime import datetime, timedelta

# Base URL of the API endpoint
base_url = "https://your-system.woow.no/api/tickets"  # Replace with your endpoint

# Authorization token (Basic Authentication)
headers = {
    "Authorization": "Basic your_access_token"  # Replace with your actual token
}

# Required date parameters (Unix timestamps in seconds)
# Example: Last 30 days
date_end = int(datetime.now().timestamp())
date_init = int((datetime.now() - timedelta(days=30)).timestamp())

# Pagination variables (0-based)
page = 0
all_items = []
delay_seconds = 1  # Delay between requests

try:
    while True:
        # Make a GET request to fetch the current page
        params = {
            "date_init": date_init,
            "date_end": date_end,
            "page": page,
            "count_elements": 100,  # Max 200
            "order": "DESC"
        }
        
        response = requests.get(base_url, params=params, headers=headers, timeout=10)
        response.raise_for_status()  # Raise an exception for HTTP errors
        
        # Parse JSON response
        data = response.json()
        
        # Check if we have items (API returns {count, page, items})
        if not data.get("items") or len(data["items"]) == 0:
            break  # Exit loop if no more results

        # Add current page items to the list
        all_items.extend(data["items"])
        print(f"Page {page} fetched successfully. Total items so far: {len(all_items)}/{data.get('count', 0)}")

        # Check if we've fetched all items
        if len(all_items) >= data.get("count", 0):
            break

        # Increment the page counter
        page += 1

        # Delay before the next request
        time.sleep(delay_seconds)

except requests.exceptions.HTTPError as e:
    if e.response.status_code == 400:
        print(f"Bad Request: {e.response.text}")
    elif e.response.status_code == 401:
        print(f"Unauthorized: Check your access token")
    else:
        print(f"HTTP Error {e.response.status_code}: {e}")
except requests.exceptions.RequestException as e:
    print(f"Error during API call: {e}")

print(f"Total items fetched: {len(all_items)}")

Using Node.js to Collect Paginated API Data

Below is an example of collecting paginated API data using Node.js. The script makes paginated requests synchronously, respecting a delay between requests to avoid overwhelming the server. It also recommends running the script outside business hours.

const axios = require('axios');

// Base URL of the API endpoint
const baseURL = "https://your-system.woow.no/api/tickets"; // Replace with your endpoint

// Authorization token (Basic Authentication)
const headers = {
    Authorization: "Basic your_access_token" // Replace with your actual token
};

// Required date parameters (Unix timestamps in seconds)
// Example: Last 30 days
const dateEnd = Math.floor(Date.now() / 1000);
const dateInit = Math.floor((Date.now() - 30 * 24 * 60 * 60 * 1000) / 1000);

// Pagination variables (0-based)
let page = 0;
const allItems = [];
const delayMilliseconds = 1000; // 1-second delay between requests

(async () => {
    console.log("Starting API data collection. Consider executing this script outside business hours.");

    try {
        while (true) {
            console.log(`Fetching page ${page}...`);
            
            // Fetch the current page with required parameters
            const response = await axios.get(baseURL, {
                params: {
                    date_init: dateInit,
                    date_end: dateEnd,
                    page: page,
                    count_elements: 100, // Max 200
                    order: 'DESC'
                },
                headers,
                timeout: 10000 // 10-second timeout for the request
            });

            const data = response.data;

            // Exit loop if no more items (API returns {count, page, items})
            if (!data.items || data.items.length === 0) {
                console.log("No more items to fetch.");
                break;
            }

            // Append current page items to the list
            allItems.push(...data.items);
            console.log(`Page ${page} fetched successfully. Total items so far: ${allItems.length}/${data.count || 0}`);

            // Check if we've fetched all items
            if (allItems.length >= (data.count || 0)) {
                break;
            }

            // Increment page counter
            page++;

            // Delay before the next request
            await new Promise(resolve => setTimeout(resolve, delayMilliseconds));
        }
    } catch (error) {
        if (error.response) {
            if (error.response.status === 400) {
                console.error(`Bad Request: ${error.response.data.error || error.response.data.message}`);
            } else if (error.response.status === 401) {
                console.error(`Unauthorized: Check your access token`);
            } else {
                console.error(`HTTP Error ${error.response.status}: ${error.response.data}`);
            }
        } else {
            console.error(`Error during API call: ${error.message}`);
        }
    }

    console.log(`Total items fetched: ${allItems.length}`);
})();

Key Benefits of This Approach

1) Server Stability: By fetching pages sequentially with delays, you minimize server stress and avoid potential rate limits.

2) Error Handling: Implementing retries ensures that temporary issues don't disrupt the entire data retrieval process.

3) Scalability: This approach can be adjusted with configurable delays or adaptive strategies based on server feedback.

4) Proper API Usage: Examples include required date parameters and correct authentication format, ensuring successful API calls.

Common Pitfalls to Avoid

  1. Forgetting Date Parameters: All endpoints require date_init and date_end. Missing these will result in a 400 error.

  2. Incorrect Authentication Format: Use Authorization: Basic {token} not Bearer {token}.

  3. Wrong Page Numbering: Pages start at 0, not 1. Starting at page 1 will skip the first page of results.

  4. Exceeding Date Range: Date ranges cannot exceed 3 years. Plan your data collection accordingly.

  5. Ignoring Response Structure: The API returns items not results. Make sure your code checks the correct field.

Error Handling

When making API calls, be prepared to handle these common errors:

For more details, see Error Codes.


Feel free to adapt these examples to your preferred programming language or framework. If you encounter issues or have specific requirements, please contact us for guidance.