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! 🚀