Skip to main content

Quick Start Guide

Get up and running with the Pixieset API in minutes. This guide will walk you through authentication, making your first API call, and implementing common workflows.

Important Notice

This is unofficial, reverse-engineered documentation. The Pixieset API is not publicly documented and may change without notice. Use at your own risk.

Prerequisites

Before you begin, you'll need:

  • A Pixieset Studio or Gallery account
  • Basic knowledge of HTTP/REST APIs
  • A tool for making HTTP requests (curl, Postman, or a programming language)

Step 1: Authentication

The Pixieset API uses session-based authentication with cookies. You'll need to log in through the web interface first.

// First, log in via the Pixieset web interface
// Then make authenticated requests with credentials included

const response = await fetch('https://studio.pixieset.com/api/v1/clients/', {
credentials: 'include', // This includes cookies
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
}
});

const data = await response.json();
console.log('Clients:', data);

Step 2: Your First API Call

Let's fetch your client list - one of the most common operations.

async function getClients() {
try {
const response = await fetch('https://studio.pixieset.com/api/v1/clients/', {
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
}
});

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

const data = await response.json();

// Process the clients
data.data.forEach(client => {
console.log(`${client.first_name} ${client.last_name} - ${client.email}`);
});

// Check pagination
console.log(`Page ${data.meta.current_page} of ${data.meta.last_page}`);

return data;
} catch (error) {
console.error('Error fetching clients:', error);
}
}

// Call the function
getClients();

Step 3: Common Workflows

Create a New Client

async function createClient(clientData) {
const response = await fetch('https://studio.pixieset.com/api/v1/clients/', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
body: JSON.stringify({
first_name: clientData.firstName,
last_name: clientData.lastName,
email: clientData.email,
phone: clientData.phone
})
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.message || 'Failed to create client');
}

const newClient = await response.json();
console.log('Created client:', newClient.data.id);
return newClient.data;
}

// Usage
createClient({
firstName: 'John',
lastName: 'Doe',
email: 'john.doe@example.com',
phone: '+1-555-123-4567'
});

Fetch Invoices with Pagination

async function getAllInvoices() {
let allInvoices = [];
let currentPage = 1;
let hasMore = true;

while (hasMore) {
const response = await fetch(
`https://studio.pixieset.com/api/v1/invoices/?page=${currentPage}&per_page=50`,
{
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
}
}
);

const data = await response.json();
allInvoices = allInvoices.concat(data.data);

// Check if there are more pages
hasMore = currentPage < data.meta.last_page;
currentPage++;

console.log(`Fetched page ${currentPage - 1} of ${data.meta.last_page}`);
}

console.log(`Total invoices: ${allInvoices.length}`);
return allInvoices;
}

// Usage
getAllInvoices().then(invoices => {
// Process all invoices
const totalAmount = invoices.reduce((sum, inv) => sum + inv.amount, 0);
console.log(`Total invoiced: ${totalAmount / 100}`); // Convert from cents
});

Step 4: Error Handling

Always implement proper error handling in your integration:

class PixiesetAPI {
constructor() {
this.baseUrl = 'https://studio.pixieset.com/api/v1';
}

async request(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;

try {
const response = await fetch(url, {
...options,
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
...options.headers
}
});

// Handle different status codes
if (response.status === 401) {
throw new Error('Authentication required. Please log in.');
}

if (response.status === 404) {
throw new Error('Resource not found');
}

if (response.status === 422) {
const error = await response.json();
throw new Error(`Validation failed: ${JSON.stringify(error.details)}`);
}

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

return await response.json();

} catch (error) {
console.error(`API Error for ${endpoint}:`, error.message);
throw error;
}
}

// Example methods using the error-handled request
async getClients() {
return this.request('/clients/');
}

async createClient(data) {
return this.request('/clients/', {
method: 'POST',
body: JSON.stringify(data)
});
}
}

// Usage
const api = new PixiesetAPI();

api.getClients()
.then(clients => console.log('Clients:', clients))
.catch(error => console.error('Failed to get clients:', error));

Step 5: Working with IDs

Pixieset uses specific ID formats for different resources. Always validate IDs:

// ID Validation Helper
const validateId = (id, type) => {
const patterns = {
client: /^cl_[A-Za-z0-9]{30}$/,
invoice: /^in_[A-Za-z0-9]{30}$/,
payment: /^ip_[A-Za-z0-9]{30}$/,
contract: /^co_[A-Za-z0-9]{30}$/
};

const pattern = patterns[type];
if (!pattern) {
throw new Error(`Unknown resource type: ${type}`);
}

if (!pattern.test(id)) {
throw new Error(`Invalid ${type} ID format: ${id}`);
}

return true;
};

// Usage
const clientId = 'cl_ABC123DEF456GHI789JKL012MNO345';

try {
validateId(clientId, 'client');
// Proceed with API call
console.log('Valid client ID');
} catch (error) {
console.error('Invalid ID:', error.message);
}

Complete Example: Client Management System

Here's a complete example that ties everything together:

class ClientManager {
constructor() {
this.baseUrl = 'https://studio.pixieset.com/api/v1';
}

async request(endpoint, options = {}) {
const response = await fetch(`${this.baseUrl}${endpoint}`, {
...options,
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
...options.headers
}
});

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

return response.json();
}

async searchClients(email) {
const clients = await this.request('/clients/');
return clients.data.filter(c =>
c.email.toLowerCase().includes(email.toLowerCase())
);
}

async getClientInvoices(clientId) {
// Validate client ID
if (!/^cl_[A-Za-z0-9]{30}$/.test(clientId)) {
throw new Error('Invalid client ID');
}

const invoices = await this.request(
`/invoices/?client_id=${clientId}&expand=client`
);

return invoices.data;
}

async createInvoice(clientId, items) {
const invoice = await this.request('/invoices/', {
method: 'POST',
body: JSON.stringify({
client_id: clientId,
due_date: this.getFutureDate(30), // 30 days from now
line_items: items,
send_email: true
})
});

return invoice.data;
}

getFutureDate(days) {
const date = new Date();
date.setDate(date.getDate() + days);
return date.toISOString().split('T')[0]; // YYYY-MM-DD format
}
}

// Usage Example
async function main() {
const manager = new ClientManager();

try {
// Search for a client
const clients = await manager.searchClients('john@example.com');

if (clients.length === 0) {
console.log('No clients found');
return;
}

const client = clients[0];
console.log(`Found client: ${client.first_name} ${client.last_name}`);

// Get client's invoices
const invoices = await manager.getClientInvoices(client.id);
console.log(`Client has ${invoices.length} invoices`);

// Create a new invoice
const newInvoice = await manager.createInvoice(client.id, [
{
name: 'Wedding Photography Package',
amount: 250000, // $2,500.00 in cents
quantity: 1
}
]);

console.log(`Created invoice: ${newInvoice.invoice_number}`);

} catch (error) {
console.error('Error:', error.message);
}
}

main();

Next Steps

Now that you've got the basics down, explore these areas:

Essential Reading

API References

Common Integration Points

Need Help?

Remember that this is unofficial documentation. The Pixieset API:

  • May change without notice
  • Has no official support
  • Should be used with proper error handling

Always test thoroughly in a development environment before deploying to production.

Code Resources

Download Examples

We provide example code in multiple languages:

Community Resources

Join the community to share experiences and get help:


Happy coding! 🚀