API Documentation

Everything you need to integrate user.photos into your application.

Quickstart

Get up and running in less than 5 minutes. All you need is an API key to start uploading and serving user avatars.

Before you start

You'll need an API key. to get yours instantly.

  1. Get your API key from your dashboard
  2. Upload an image using our REST API
  3. Use the returned URL in your application

Authentication

All API requests require authentication using your API key in the Authorization header.

HTTP Header
Authorization: Bearer your_api_key_here

⚠️ Keep your API key secure

Never expose your API key in client-side code or public repositories. Always use it from your backend.

Upload Images

Upload user avatars using a simple POST request. Images are automatically optimized and made available via CDN.

cURL Example

Terminal
curl -X POST https://api.user.photos/v1/upload \
  -H "Authorization: Bearer your_api_key_here" \
  -H "Content-Type: multipart/form-data" \
  -F "user_id=12345" \
  -F "image=@/path/to/avatar.jpg"

Ruby Example

Ruby (HTTParty)
require 'httparty'

class UserPhotos
  include HTTParty
  base_uri 'https://api.user.photos/v1'
  
  def initialize(api_key)
    @api_key = api_key
  end
  
  def upload_avatar(user_id, image_path)
    options = {
      headers: {
        'Authorization' => "Bearer #{@api_key}"
      },
      body: {
        user_id: user_id,
        image: File.open(image_path)
      }
    }
    
    self.class.post('/upload', options)
  end
end

# Usage
client = UserPhotos.new('your_api_key_here')
response = client.upload_avatar(12345, '/path/to/avatar.jpg')

if response.success?
  puts "Image URL: #{response['image_url']}"
else
  puts "Error: #{response['error']}"
end

Successful Response

JSON Response (200 OK)
{
  "success": true,
  "image_id": "img_1234567890abcdef",
  "user_id": "12345",
  "image_url": "https://cdn.user.photos/img_1234567890abcdef",
  "thumbnail_url": "https://cdn.user.photos/img_1234567890abcdef?w=150&h=150",
  "upload_date": "2024-01-15T10:30:00Z",
  "file_size": 245760,
  "dimensions": {
    "width": 800,
    "height": 600
  }
}

Image URL Formats

Transform images on-the-fly by adding query parameters to the base URL. All transformations are cached globally for fast delivery.

Base URL Format

URL Pattern
https://cdn.user.photos/{image_id}[?parameters]

Available Parameters

Sizing Parameters

w=200
Set width to 200px
Maintains aspect ratio
h=150
Set height to 150px
Maintains aspect ratio
w=100&h=100
Set both dimensions
Crops to fit

Quality & Format

q=80
Set quality (1-100)
Default: 85
f=webp
Force format
webp, jpg, png

URL Examples

Original Size
https://cdn.user.photos/img_1234567890abcdef
Square Thumbnail (150x150)
https://cdn.user.photos/img_1234567890abcdef?w=150&h=150
Profile Size (400px wide)
https://cdn.user.photos/img_1234567890abcdef?w=400
Optimized WebP
https://cdn.user.photos/img_1234567890abcdef?w=300&f=webp&q=80

Error Handling

Our API uses standard HTTP status codes and returns consistent error responses to help you handle issues gracefully.

Error Response Format

Error Response
{
  "success": false,
  "error": {
    "code": "INVALID_IMAGE_FORMAT",
    "message": "The uploaded file is not a valid image format",
    "details": "Only JPEG, PNG, and WebP files are supported"
  }
}

Common Error Codes

HTTP Status Codes & Error Types

401 Unauthorized INVALID_API_KEY

Missing or invalid API key in Authorization header

400 Bad Request MISSING_USER_ID

user_id parameter is required for all uploads

400 Bad Request INVALID_IMAGE_FORMAT

File is not a valid image format (JPEG, PNG, WebP only)

413 Payload Too Large FILE_TOO_LARGE

Image file exceeds 10MB size limit

429 Too Many Requests RATE_LIMIT_EXCEEDED

You've exceeded your plan's rate limits

404 Not Found IMAGE_NOT_FOUND

The requested image does not exist or has been deleted

More Code Examples

Ruby with Faraday

Ruby (Faraday)
require 'faraday'
require 'faraday/multipart'

class UserPhotos
  def initialize(api_key)
    @api_key = api_key
    @conn = Faraday.new(url: 'https://api.user.photos') do |f|
      f.request :multipart
      f.request :url_encoded
      f.adapter Faraday.default_adapter
    end
  end
  
  def upload_avatar(user_id, image_path)
    response = @conn.post('/v1/upload') do |req|
      req.headers['Authorization'] = "Bearer #{@api_key}"
      req.body = {
        user_id: user_id,
        image: Faraday::UploadIO.new(image_path, 'image/jpeg')
      }
    end
    
    JSON.parse(response.body)
  end
end

# Usage
client = UserPhotos.new('your_api_key_here')
result = client.upload_avatar('user123', 'avatar.jpg')
puts "Avatar URL: #{result['image_url']}"

JavaScript/Node.js

JavaScript
const FormData = require('form-data');
const fs = require('fs');
const fetch = require('node-fetch');

class UserPhotos {
  constructor(apiKey) {
    this.apiKey = apiKey;
  }
  
  async uploadAvatar(userId, imagePath) {
    const form = new FormData();
    form.append('user_id', userId);
    form.append('image', fs.createReadStream(imagePath));
    
    const response = await fetch('https://api.user.photos/v1/upload', {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        ...form.getHeaders()
      },
      body: form
    });
    
    return response.json();
  }
}

// Usage
const client = new UserPhotos('your_api_key_here');
client.uploadAvatar('user123', 'avatar.jpg')
  .then(result => console.log('Avatar URL:', result.image_url))
  .catch(error => console.error('Error:', error));

Need Help?

Have questions or need support? We're here to help.