Skip to main content

SignageStudio SDK Documentation

Official Developer Libraries

SignageStudio SDKs provide idiomatic access to the platform API in your preferred programming language. Handle authentication, manage resources, and integrate with your existing systems using battle-tested libraries.

Available SDKs

LanguagePackageVersionInstall
Pythonsignage-studio2.5.0pip install signage-studio
JavaScript/Node.js@signage/studio-sdk3.1.0npm install @signage/studio-sdk
PHPsignage/studio-php1.8.0composer require signage/studio-php
C#/.NETSignageStudio.SDK2.2.0dotnet add package SignageStudio.SDK

Python SDK

Installation

pip install signage-studio

Quick Start

from signage_studio import SignageClient

# Initialize client
client = SignageClient(
api_key="your_api_key",
# Or use OAuth:
# client_id="your_client_id",
# client_secret="your_client_secret"
)

# List all players
players = client.players.list()
for player in players:
print(f"{player.name}: {player.status}")

# Get a specific player
player = client.players.get("player_abc123")

# Update player
player.name = "Updated Display Name"
player.save()

# Send command to player
player.send_command("refresh")

Managing Content

from signage_studio import SignageClient
from pathlib import Path

client = SignageClient(api_key="your_api_key")

# Upload content
content = client.content.upload(
file=Path("promotion.jpg"),
name="February Promotion",
folder_id="folder_xyz",
tags=["promotion", "february"]
)

print(f"Uploaded: {content.id}")

# List content
all_content = client.content.list(type="image")

# Search content
results = client.content.search("promotion")

# Delete content
client.content.delete("content_abc123")

Campaign Management

from signage_studio import SignageClient
from datetime import date, time

client = SignageClient(api_key="your_api_key")

# Create campaign
campaign = client.campaigns.create(
name="March Campaign",
schedule={
"start_date": date(2026, 3, 1),
"end_date": date(2026, 3, 31),
"days": ["monday", "tuesday", "wednesday", "thursday", "friday"],
"start_time": time(9, 0),
"end_time": time(21, 0)
},
items=[
{"content_id": "content_abc", "duration": 10},
{"content_id": "content_def", "duration": 15}
]
)

# Assign to players
campaign.assign(
player_ids=["player_1", "player_2"],
group_ids=["group_retail"]
)

# List campaigns
active_campaigns = client.campaigns.list(status="active")

Async Support

import asyncio
from signage_studio import AsyncSignageClient

async def main():
client = AsyncSignageClient(api_key="your_api_key")

# Async operations
players = await client.players.list()

# Parallel requests
tasks = [
client.players.get(p.id) for p in players[:10]
]
details = await asyncio.gather(*tasks)

await client.close()

asyncio.run(main())

JavaScript/Node.js SDK

Installation

npm install @signage/studio-sdk
# or
yarn add @signage/studio-sdk

Quick Start

const { SignageClient } = require('@signage/studio-sdk');

// Initialize client
const client = new SignageClient({
apiKey: 'your_api_key'
});

// List players
async function listPlayers() {
const players = await client.players.list();

players.data.forEach(player => {
console.log(`${player.name}: ${player.status}`);
});
}

// Get player details
async function getPlayer(id) {
const player = await client.players.get(id);
console.log(player);
}

ES Modules / TypeScript

import { SignageClient, Player, Content } from '@signage/studio-sdk';

const client = new SignageClient({
apiKey: process.env.SIGNAGE_API_KEY!
});

async function updatePlayerContent(playerId: string): Promise<void> {
const player: Player = await client.players.get(playerId);

await client.players.sendCommand(playerId, {
command: 'refresh'
});

console.log(`Refreshed content on ${player.name}`);
}

Content Upload

const fs = require('fs');
const { SignageClient } = require('@signage/studio-sdk');

const client = new SignageClient({ apiKey: 'your_api_key' });

// Upload from file
async function uploadFromFile() {
const content = await client.content.upload({
file: fs.createReadStream('promotion.jpg'),
name: 'February Promotion',
folderId: 'folder_xyz',
tags: ['promotion', 'february']
});

console.log(`Uploaded: ${content.id}`);
}

// Upload from URL
async function uploadFromUrl() {
const content = await client.content.uploadFromUrl({
url: 'https://example.com/image.jpg',
name: 'External Image'
});

return content;
}

Webhooks Handler (Express)

const express = require('express');
const { verifyWebhook } = require('@signage/studio-sdk');

const app = express();

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-signage-signature'];

if (!verifyWebhook(req.body, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}

const event = JSON.parse(req.body);

switch (event.event) {
case 'player.offline':
console.log(`Player ${event.data.name} went offline`);
// Send alert, log to monitoring, etc.
break;
case 'content.updated':
console.log(`Content ${event.data.name} was updated`);
break;
}

res.status(200).send('OK');
});

PHP SDK

Installation

composer require signage/studio-php

Quick Start

<?php
require_once 'vendor/autoload.php';

use Signage\StudioSDK\SignageClient;

// Initialize client
$client = new SignageClient([
'api_key' => 'your_api_key'
]);

// List players
$players = $client->players->list();

foreach ($players->data as $player) {
echo "{$player->name}: {$player->status}\n";
}

// Get specific player
$player = $client->players->get('player_abc123');

// Update player
$client->players->update('player_abc123', [
'name' => 'Updated Display Name'
]);

// Send command
$client->players->sendCommand('player_abc123', 'refresh');

Content Management

<?php
use Signage\StudioSDK\SignageClient;

$client = new SignageClient(['api_key' => 'your_api_key']);

// Upload content
$content = $client->content->upload([
'file' => fopen('promotion.jpg', 'r'),
'name' => 'February Promotion',
'folder_id' => 'folder_xyz',
'tags' => ['promotion', 'february']
]);

echo "Uploaded: {$content->id}\n";

// List content
$allContent = $client->content->list([
'type' => 'image',
'per_page' => 50
]);

// Delete content
$client->content->delete('content_abc123');

Laravel Integration

<?php
// config/signage.php
return [
'api_key' => env('SIGNAGE_API_KEY'),
];

// app/Providers/SignageServiceProvider.php
namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Signage\StudioSDK\SignageClient;

class SignageServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton(SignageClient::class, function ($app) {
return new SignageClient([
'api_key' => config('signage.api_key')
]);
});
}
}

// Usage in controller
public function index(SignageClient $signage)
{
$players = $signage->players->list();
return view('players.index', compact('players'));
}

.NET SDK

Installation

dotnet add package SignageStudio.SDK

Quick Start

using SignageStudio.SDK;

// Initialize client
var client = new SignageClient(new SignageClientOptions
{
ApiKey = "your_api_key"
});

// List players
var players = await client.Players.ListAsync();

foreach (var player in players.Data)
{
Console.WriteLine($"{player.Name}: {player.Status}");
}

// Get specific player
var player = await client.Players.GetAsync("player_abc123");

// Update player
await client.Players.UpdateAsync("player_abc123", new PlayerUpdateRequest
{
Name = "Updated Display Name"
});

// Send command
await client.Players.SendCommandAsync("player_abc123", PlayerCommand.Refresh);

Dependency Injection

// Startup.cs or Program.cs
services.AddSignageStudio(options =>
{
options.ApiKey = Configuration["Signage:ApiKey"];
});

// Controller
public class PlayersController : Controller
{
private readonly ISignageClient _signage;

public PlayersController(ISignageClient signage)
{
_signage = signage;
}

public async Task<IActionResult> Index()
{
var players = await _signage.Players.ListAsync();
return View(players);
}
}

Async Patterns

using SignageStudio.SDK;

var client = new SignageClient(options);

// Parallel operations
var playerTasks = playerIds.Select(id => client.Players.GetAsync(id));
var players = await Task.WhenAll(playerTasks);

// Cancellation support
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var result = await client.Content.UploadAsync(stream, "name", cts.Token);

Common Patterns

Error Handling

All SDKs provide consistent error handling:

# Python
from signage_studio import SignageClient
from signage_studio.exceptions import (
SignageError,
AuthenticationError,
NotFoundError,
RateLimitError,
ValidationError
)

client = SignageClient(api_key="your_api_key")

try:
player = client.players.get("invalid_id")
except NotFoundError:
print("Player not found")
except AuthenticationError:
print("Invalid API key")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after} seconds")
except ValidationError as e:
print(f"Validation error: {e.errors}")
except SignageError as e:
print(f"API error: {e.message}")

Pagination

# Python - iterate all pages
for player in client.players.list_all():
print(player.name)

# Manual pagination
page = client.players.list(page=1, per_page=50)
while page.has_more:
for player in page.data:
process(player)
page = page.next_page()
// JavaScript - iterate all pages
for await (const player of client.players.listAll()) {
console.log(player.name);
}

Retry Logic

SDKs include automatic retry for transient failures:

# Python - configure retries
client = SignageClient(
api_key="your_api_key",
max_retries=3,
retry_delay=1.0, # seconds
retry_on=[429, 500, 502, 503, 504]
)

Frequently Asked Questions


Next Steps


SDK documentation maintained by MediaSignage. Report issues on GitHub or contact developers@digitalsignage.com