SignageStudio API Reference
Build Powerful Integrations
The SignageStudio REST API enables developers to programmatically manage content, players, schedules, and campaigns. Integrate digital signage with your existing systems, automate content updates, and build custom applications on top of the SignageStudio platform.
API Overview
Base URL
Production: https://api.signage.me/v1
Sandbox: https://sandbox-api.signage.me/v1
Key Features
| Feature | Description |
|---|---|
| RESTful Design | Standard HTTP methods, JSON responses |
| OAuth 2.0 | Secure authentication |
| Rate Limiting | Fair usage protection |
| Webhooks | Real-time event notifications |
| Pagination | Efficient large dataset handling |
| Versioning | Stable, predictable updates |
Authentication
OAuth 2.0
SignageStudio API uses OAuth 2.0 for authentication. All API requests require a valid access token.
Getting Credentials
- Log in to SignageStudio
- Navigate to Settings → API & Integrations
- Click Create API Application
- Note your
client_idandclient_secret
Token Request
POST https://api.signage.me/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
Response
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "read write"
}
Using the Token
Include the token in the Authorization header:
GET https://api.signage.me/v1/players
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
API Keys (Simple Authentication)
For simpler integrations, API keys are available:
GET https://api.signage.me/v1/players
X-API-Key: your_api_key_here
Security Note: API keys should only be used for server-to-server communication. Never expose API keys in client-side code.
Rate Limiting
Limits
| Plan | Requests/Minute | Requests/Day |
|---|---|---|
| Free | 60 | 1,000 |
| Pro | 300 | 10,000 |
| Enterprise | 1,000 | 100,000 |
Rate Limit Headers
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 299
X-RateLimit-Reset: 1706745600
Handling Rate Limits
When rate limited, the API returns:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
{
"error": "rate_limit_exceeded",
"message": "Too many requests. Please retry after 60 seconds."
}
Core Resources
Players
Players are the devices running SignageStudio software.
List Players
GET /v1/players
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
status | string | Filter by status: online, offline, all |
group_id | string | Filter by player group |
page | integer | Page number (default: 1) |
per_page | integer | Items per page (default: 25, max: 100) |
Response:
{
"data": [
{
"id": "player_abc123",
"name": "Lobby Display 1",
"status": "online",
"last_seen": "2026-02-01T14:30:00Z",
"ip_address": "192.168.1.100",
"version": "5.2.1",
"display": {
"resolution": "1920x1080",
"orientation": "landscape"
},
"location": {
"name": "Main Office",
"address": "123 Main St"
},
"group_id": "group_xyz789",
"campaign_id": "campaign_def456",
"created_at": "2025-06-15T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total_count": 47,
"total_pages": 2
}
}
Get Player
GET /v1/players/{player_id}
Update Player
PATCH /v1/players/{player_id}
Content-Type: application/json
{
"name": "Updated Display Name",
"group_id": "group_newgroup"
}
Player Commands
POST /v1/players/{player_id}/commands
Content-Type: application/json
{
"command": "restart",
"parameters": {}
}
Available Commands:
| Command | Description |
|---|---|
restart | Restart player software |
reboot | Reboot device |
refresh | Refresh content |
screenshot | Capture screenshot |
clear_cache | Clear local cache |
Content
Content includes media files, layouts, and scenes.
List Content
GET /v1/content
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
type | string | image, video, layout, scene, widget |
folder_id | string | Filter by folder |
search | string | Search by name |
Response:
{
"data": [
{
"id": "content_abc123",
"name": "Summer Promotion",
"type": "image",
"mime_type": "image/jpeg",
"file_size": 2456789,
"dimensions": {
"width": 1920,
"height": 1080
},
"duration": null,
"thumbnail_url": "https://cdn.signage.me/thumbs/abc123.jpg",
"url": "https://cdn.signage.me/content/abc123.jpg",
"folder_id": "folder_xyz",
"tags": ["summer", "promotion", "retail"],
"created_at": "2026-01-15T09:00:00Z",
"updated_at": "2026-01-20T14:30:00Z"
}
],
"meta": {
"current_page": 1,
"total_count": 234
}
}
Upload Content
POST /v1/content
Content-Type: multipart/form-data
file: [binary]
name: "New Promotion"
folder_id: "folder_xyz"
tags: ["promotion", "2026"]
Response:
{
"id": "content_new123",
"name": "New Promotion",
"type": "image",
"status": "processing",
"upload_url": null,
"created_at": "2026-02-01T15:00:00Z"
}
Delete Content
DELETE /v1/content/{content_id}
Campaigns
Campaigns are playlists that combine content with scheduling.
List Campaigns
GET /v1/campaigns
Create Campaign
POST /v1/campaigns
Content-Type: application/json
{
"name": "February Promotions",
"description": "Monthly promotional campaign",
"schedule": {
"start_date": "2026-02-01",
"end_date": "2026-02-28",
"days": ["monday", "tuesday", "wednesday", "thursday", "friday"],
"start_time": "09:00",
"end_time": "21:00"
},
"items": [
{
"content_id": "content_abc123",
"duration": 10,
"order": 1
},
{
"content_id": "content_def456",
"duration": 15,
"order": 2
}
],
"player_groups": ["group_xyz789"]
}
Assign Campaign to Players
POST /v1/campaigns/{campaign_id}/assign
Content-Type: application/json
{
"player_ids": ["player_abc", "player_def"],
"group_ids": ["group_xyz"]
}
Schedules
Advanced scheduling for content playback.
Create Schedule
POST /v1/schedules
Content-Type: application/json
{
"name": "Lunch Menu",
"campaign_id": "campaign_abc123",
"rules": [
{
"type": "time_range",
"start_time": "11:00",
"end_time": "14:00"
},
{
"type": "days",
"days": ["monday", "tuesday", "wednesday", "thursday", "friday"]
}
],
"priority": 10
}
Schedule Rule Types
| Type | Parameters | Description |
|---|---|---|
time_range | start_time, end_time | Time of day |
date_range | start_date, end_date | Date range |
days | days[] | Days of week |
recurring | interval, unit | Recurring pattern |
weather | condition, threshold | Weather-triggered |
custom | expression | Custom logic |
Webhooks
Receive real-time notifications for events.
Register Webhook
POST /v1/webhooks
Content-Type: application/json
{
"url": "https://your-server.com/webhook",
"events": ["player.online", "player.offline", "content.updated"],
"secret": "your_webhook_secret"
}
Webhook Events
| Event | Description |
|---|---|
player.online | Player connected |
player.offline | Player disconnected |
player.error | Player reported error |
content.created | New content uploaded |
content.updated | Content modified |
content.deleted | Content removed |
campaign.started | Campaign began playing |
campaign.ended | Campaign completed |
Webhook Payload
{
"event": "player.offline",
"timestamp": "2026-02-01T14:30:00Z",
"data": {
"player_id": "player_abc123",
"name": "Lobby Display 1",
"last_seen": "2026-02-01T14:25:00Z"
},
"signature": "sha256=abc123..."
}
Verifying Webhooks
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
Error Handling
Error Response Format
{
"error": {
"code": "invalid_request",
"message": "The request was invalid.",
"details": [
{
"field": "name",
"message": "Name is required"
}
]
}
}
HTTP Status Codes
| Code | Meaning |
|---|---|
200 | Success |
201 | Created |
204 | No Content (success, no body) |
400 | Bad Request |
401 | Unauthorized |
403 | Forbidden |
404 | Not Found |
409 | Conflict |
422 | Validation Error |
429 | Rate Limited |
500 | Server Error |
Common Error Codes
| Code | Description |
|---|---|
invalid_request | Malformed request |
authentication_required | Missing auth |
invalid_token | Bad/expired token |
insufficient_permissions | Access denied |
resource_not_found | Entity not found |
validation_error | Invalid data |
rate_limit_exceeded | Too many requests |
Code Examples
Python
import requests
API_KEY = "your_api_key"
BASE_URL = "https://api.signage.me/v1"
headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
}
# List all players
response = requests.get(f"{BASE_URL}/players", headers=headers)
players = response.json()
for player in players["data"]:
print(f"{player['name']}: {player['status']}")
# Update player content
response = requests.post(
f"{BASE_URL}/players/player_abc123/commands",
headers=headers,
json={"command": "refresh"}
)
JavaScript/Node.js
const axios = require('axios');
const api = axios.create({
baseURL: 'https://api.signage.me/v1',
headers: {
'X-API-Key': 'your_api_key'
}
});
// List players
async function getPlayers() {
const { data } = await api.get('/players');
return data.data;
}
// Upload content
async function uploadContent(file, name) {
const formData = new FormData();
formData.append('file', file);
formData.append('name', name);
const { data } = await api.post('/content', formData, {
headers: { 'Content-Type': 'multipart/form-data' }
});
return data;
}
cURL
# List players
curl -X GET "https://api.signage.me/v1/players" \
-H "X-API-Key: your_api_key"
# Create campaign
curl -X POST "https://api.signage.me/v1/campaigns" \
-H "X-API-Key: your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "New Campaign",
"items": [
{"content_id": "content_123", "duration": 10}
]
}'
SDKs and Libraries
Official SDKs
| Language | Package | Repository |
|---|---|---|
| Python | signage-studio | GitHub |
| JavaScript | @signage/studio-sdk | npm |
| PHP | signage/studio-php | Packagist |
| C#/.NET | SignageStudio.SDK | NuGet |
Installation
# Python
pip install signage-studio
# Node.js
npm install @signage/studio-sdk
# PHP
composer require signage/studio-php
Frequently Asked Questions
Next Steps
- SDK Documentation - Language-specific SDKs
- Network Requirements - API connectivity
- Security Best Practices - API security
- Troubleshooting - Common issues
API documentation maintained by MediaSignage. For support, contact developers@digitalsignage.com