⚑ You are viewing the modern Pirsonal Developer Documentation Hub (v2). (Prefer the classic getting started guide?)
Switch to Classic Documentation Index β†—

Pirsonal Developer Documentation Hub

Welcome to the comprehensive Pirsonal developer platform. Learn how to architect, automate, and scale dynamic video generation workflows across your CRM, web applications, or marketing pipelines.

πŸ—οΈ High-Volume Rendering Architecture

Video generation is compute-intensive. To guarantee low latency and non-blocking performance, Pirsonal operates an asynchronous distributed rendering architecture:

1
1. Define Template
Create reusable video blueprints via Pirsonal Studio (previously called Pirsonal Editor) or Template_New defining placeholders.
2
2. Dispatch Render
Call Template_Video_New with personalized dynamic media. The job is queued in <100ms.
3
3. GPU/CPU Workers
Distributed rendering workers pull jobs from Gearman distributed job queues, compositing frames and encoding MP4 video.
4
4. Webhook & Landing Page
Upon render completion, Pirsonal delivers an HTTP POST webhook with download URLs, landing page links, and player embed codes.
☁️ Video Output Storage & Cloud File Naming Specifications

Rendered videos are encoded into high-quality MP4 media assets and uploaded directly to your designated cloud storage provider. Understanding file naming and object key formatting is critical for automated media ingestion, downstream pipelines, and S3 event workflows:

Pirsonal Cloud / Azure Blob Storage

Configured via videoOutput: { "type": "pirsonal" }. Files are hosted in Pirsonal-managed highly available blob storage containers.

Container Path: <accountID>/<videoID>.<profile>.mp4
Video File ID: <videoID>.<profile>.mp4
* Standard single extension format.
Amazon Web Services (AWS S3)

Configured via videoOutput: { "type": "awsS3", "awsS3Bucket": "my-bucket" }. Worker streams media directly into your S3 bucket.

S3 Object Key: <videoID>.<profile>.mp4.mp4
Public / Direct URL: https://<bucket>.s3.amazonaws.com/<videoID>.<profile>.mp4.mp4
* Double extension (.mp4.mp4) preserved by background worker.
Custom Profiles (customProfiles) Naming & Sanitization Rule: When a template declares custom rendering profiles, you MUST specify that custom profile's exact name in outProfiles (e.g. ["MyCustom720p"]). The rendering engine replaces whitespace with underscores (_). Always use URL-safe alphanumeric characters, hyphens, and underscores ([a-zA-Z0-9_-]), and never pass slashes, dots, query parameters, or file extensions. The rendering engine will assign the output file using your specified custom profile name (e.g., Azure/Pirsonal Cloud: <videoID>.MyCustom720p.mp4; S3: <videoID>.MyCustom720p.mp4.mp4).
🌐 Personalized Landing Pages & Interactive Video Player

Pirsonal is not just an MP4 rendering service. Every video generated is instantly paired with a personalized landing page and interactive player tailored to convert each viewer:

1. Dynamic Landing Pages
Hosted on vid.pirsonal.com or your custom branded domain (e.g. videos.yourbrand.com). Each page dynamically adapts headlines, body text, customized buttons, and OpenGraph social sharing previews for each contact.
2. Interactive HTML5 Player
Embeddable anywhere via iframe or script. In-video Call-To-Action (CTA) buttons trigger at exact timecodes (configured via cta.startTime) to prompt viewers to buy, schedule a demo, or download collateral while watching.
3. Actionable Analytics
Tracks viewer behavior including total plays, engagement rates, and interactive in-video CTA clicksβ€”queryable via Video_Get and aggregated in the Pirsonal dashboard.
πŸ”„ Video State Lifecycle

When querying Video_Get or receiving webhooks, a video transitions through the following discrete lifecycle states:

1. queued: Request accepted and structurally validated by the API server. Awaiting available worker slot. Dynamic asset fetching (images, audio) and rendering validation occur asynchronously when a worker claims the task.
2. processing: Worker is rendering video frames and encoding output profiles.
3. done: Video finalized, stored in cloud storage, and ready for streaming, landing page viewing, or download.
4. error: Render failed (e.g. dynamic image URL 404, invalid audio codec, bad font). Error details are present in video.status.error. See Common API & Rendering Errors.
πŸ”‘ Identifier Distinction: videoID vs. pirsonalID

To prevent integration ambiguity, Pirsonal strictly distinguishes between media assets stored in your account library and rendered video instances:

🎬 videoID (Video Output Instance)

The unique identifier returned when rendering a personalized video via Template_Video_New (or VideoInfo_t.id).

  • Represents a specific rendered personalized MP4 video file and its landing page.
  • Used in Video_Get, Video_Update, Video_Delete, landing page URLs (vid.pirsonal.com/v/<videoID>), and webhook payloads.
πŸ“ pirsonalID (Media Asset Identifier)

The unique identifier for a reusable asset uploaded to your account's Media Library (or Media_t.id).

  • Represents a source media file (e.g., logo PNG, background MP4, soundtrack MP3) managed via Media_Upload / Media_List.
  • Referenced inside template scripts or dynamic payloads via inputMedias: [{ "pirsonalID": "..." }].

πŸ”’ Webhook Delivery & Authentication

When video rendering concludes (success or error), Pirsonal dispatches an HTTP POST request to your configured webhook URL with User-Agent: Pirsonal and the complete VideoInfo_t JSON payload. If configured on the template (template.webhook.user and template.webhook.pass), Pirsonal protects delivery using HTTP Basic authentication.

Delivery Guarantees: The worker executes a single HTTP POST per completion event without automatic retry on HTTP failure. Webhook receivers must acknowledge with HTTP 200 within a few seconds, handle deliveries idempotently using video.id, and maintain an asynchronous fallback polling reconciliation worker using Video_Get for any videos remaining in queued or processing states beyond expected rendering duration.

EXPRESS.JS WEBHOOK RECEIVER & FAIL-CLOSED AUTHENTICATION
const express = require('express');
const app = express();
app.use(express.json());

app.post('/webhooks/pirsonal', (req, res) => {
  // 1. Enforce HTTP Basic Authentication strictly (fail-closed)
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Basic ')) {
    res.setHeader('WWW-Authenticate', 'Basic realm="PirsonalWebhook"');
    return res.status(401).send('Unauthorized');
  }

  const base64Credentials = authHeader.split(' ')[1];
  const [user, pass] = Buffer.from(base64Credentials, 'base64').toString().split(':');
  if (user !== process.env.WEBHOOK_USER || pass !== process.env.WEBHOOK_PASS) {
    return res.status(401).send('Unauthorized');
  }

  // 2. Consume authentic VideoInfo_t payload
  const video = req.body;
  console.log('Video completed:', video.id, 'Status:', video.status.code);

  if (video.status.code === 'done') {
    console.log('Output files generated:', video.outFiles);
    // Dynamic player / landing page URL:
    const landingUrl = video.shortUrl || `https://vid.pirsonal.com/v/${video.id}`;
    console.log('View video at:', landingUrl);
  } else if (video.status.code === 'error') {
    console.error('Rendering error reason:', video.status.error);
  }

  // 3. Promptly acknowledge receipt with HTTP 200
  res.status(200).json({ received: true, id: video.id });
});
πŸš€ Enterprise Scale & Reliability Best Practices
  • Combine Webhooks with Polling Reconciliation: Rely on webhooks for real-time completion events, but run a background reconciliation cron that queries Video_Get for any items outstanding after 10 minutes to guarantee complete resilience.
  • CDN-Hosted Dynamic Assets: Ensure dynamic images and audio URLs are hosted on high-throughput CDNs (e.g. CloudFront, Cloudflare, S3) with CORS enabled.
  • Asset Caching & Dimensions: Size dynamic images to match or slightly exceed their rendered bounding box to optimize rendering speed.