connectVFX External API: Integration Guide

Welcome to the connectVFX Job Integration API. This guide provides the documentation required to connect to our job listings database, query available roles, and integrate them into your own application, website, or Discord channels.

Download OpenAPI Spec (openapi.yaml)


Data Licensing & Commercial Scope

ConnectVFX aggregates, verifies, and normalizes visual effects, 3D animation, and gaming jobs into a clean, developer-ready dataset. We provide two core interfaces:

Interface Pricing Delivery Mode Access Scope Attribution Requirement
Free Community Feed Free ($0) Discord / Slack Webhooks Real-time push for new active job listings Built-in embed footer link to connectvfx.app
Developer REST API $39 / mo REST JSON Feed (Self-Serve) Active job catalog, normalized software, studio taxonomy & compensation Visible "Powered by ConnectVFX" product link + job links to job_url

Note: Developer API subscriptions grant access for internal tools, community bots, mobile widgets, and niche job boards. Wholesale replication or standalone reselling of raw database records is strictly prohibited.


Canonical URLs & Application Routing

Every job record contains two standardized URLs:

  • job_url (Canonical Listing Record): https://connectvfx.app/jobs/studio-slug/role-slug — ConnectVFX's permanent, SEO-indexable representation of the job listing. Used for public attribution and candidate detail navigation.
  • apply_url (Current Application Destination): https://connectvfx.app/api/apply?id=job_...&ref=pub_id — Direct candidate application route pointing to the studio's active application portal when available.

Authentication & Security

All requests to the Developer API must be authenticated using an API Key sent in the HTTP Authorization header.

Security Rules

  • Backend-to-Backend Only: You must perform all API requests from your own backend server (e.g. Node.js, Python, or bot server). Never call the API directly from client-side browser JavaScript to avoid leaking your secret key.
  • HTTPS Required: All connections require TLS/HTTPS encryption.

Request Headers

Include the following headers with every request:

Authorization: Bearer YOUR_SECRET_API_KEY
Content-Type: application/json

Endpoints

Get Active Jobs

Retrieves a paginated list of active, verified visual effects, animation, and gaming job listings.

  • URL: https://connectvfx.app/api/external-jobs
  • Method: GET
  • Content-Type: application/json

Query Parameters

Parameter Type Default Description
software String None Filter for roles requiring specific software (e.g., Houdini, Nuke, Unreal, Maya, Blender).
search String None Case-insensitive text search matching job titles, studios, or locations.
limit Integer 50 Number of results to return per page. Min: 1, Max: 100.
page Integer 0 Page index (0-indexed).

Response Schema

The API returns a JSON object containing pagination metadata and an array of verified active job listings:

{
  "jobs": [
    {
      "id": "job_e83f912a781b",
      "uuid": "45ff7619-d5c5-49fa-bd36-77c6e97aed8a",
      "title": "Senior FX Animator (Houdini)",
      "discipline": "FX / Simulation",
      "seniority": "Senior",
      "company": "Industrial Light & Magic",
      "company_slug": "industrial-light-magic",
      "displayLocation": "Vancouver, Canada",
      "city": "Vancouver",
      "country": "Canada",
      "country_iso": "CA",
      "is_remote": false,
      "contract_type": "full-time",
      "softwares": {
        "must": ["Houdini"],
        "bonus": ["Nuke", "Python"]
      },
      "description_snippet": "We are seeking a Senior FX Animator to create photorealistic fluid and pyro simulations...",
      "studio_location_hq": "San Francisco, CA, USA",
      "studio_employee_count": "1000-5000",
      "studio_size_category": "Major Studio",
      "studio_locations": "San Francisco, Vancouver, London, Singapore, Sydney",
      "salary_raw": "$115,000 - $140,000 / year",
      "salary_currency_local": "USD",
      "salary_min_usd": 115000,
      "salary_max_usd": 140000,
      "job_url": "https://connectvfx.app/jobs/industrial-light-magic/senior-fx-animator-houdini",
      "apply_url": "https://connectvfx.app/api/apply?id=job_e83f912a781b&ref=pub_your_id",
      "firstSeen": "2026-08-10T14:30:00.000Z",
      "lastSeen": "2026-08-14T08:00:00.000Z",
      "is_active": true
    }
  ],
  "total": 845,
  "page": 0,
  "limit": 50,
  "pages_total": 17
}

Rate Limits, Freshness & Attribution

  • Monthly API Quota: Configured based on your approved tier (Developer, Professional, or Enterprise).
  • Rate Limits: Standard rate limits apply per API key as specified in your welcome confirmation.
  • Product-Level Attribution: Public displays must show a clearly visible "Powered by ConnectVFX" link pointing to https://connectvfx.app.
  • Job Links: Individual job listings must retain a clickable link to their corresponding job_url.
  • Maintained Freshness: ConnectVFX continuously updates listing validity (is_active: true). Consumers should synchronize at least every 24–48 hours.
  • Edge Caching: Results are cached across global edge locations with stale-while-revalidate.

Developer Security & Usage Terms

  • Backend-Only Execution: API keys must only be invoked from secure server-side environments (Node.js, Python, Go, Cloud Functions, etc.). Never embed API keys in browser JavaScript or mobile client binaries.
  • Caching Permitted: You are encouraged to cache API responses in your database or Redis layer for up to 48 hours to minimize latency.
  • Acceptable Use: Automated scraping of the API or wholesale database harvesting for re-licensing without authorization is prohibited.

Privacy & Data Governance

The Connect VFX External API exposes public and normalized industry hiring data. We do not expose personal applicant records or confidential studio contact data through developer tiers. For data inquiries, contact sales@connectvfx.app.


Integration Examples

Node.js (Backend Fetch)

const axios = require('axios');

const API_URL = 'https://connectvfx.app/api/external-jobs';
const API_KEY = process.env.CONNECTVFX_API_KEY;

async function fetchHoudiniJobs() {
    try {
        const response = await axios.get(API_URL, {
            headers: {
                'Authorization': `Bearer ${API_KEY}`
            },
            params: {
                software: 'Houdini',
                limit: 10
            }
        });
        
        console.log(`Found ${response.data.total} Houdini jobs:`);
        response.data.jobs.forEach(job => {
            console.log(`- [${job.company}] ${job.title} (${job.displayLocation})`);
            console.log(`  Details: ${job.job_url}`);
            console.log(`  Apply Direct: ${job.apply_url}`);
        });
    } catch (error) {
        console.error('API Error:', error.response?.data || error.message);
    }
}

fetchHoudiniJobs();

Python (Discord Bot Integration)

import requests
import discord
from discord.ext import tasks, commands

API_URL = "https://connectvfx.app/api/external-jobs"
API_KEY = "your_api_key_here"
CHANNEL_ID = 123456789012345678

class JobBoardCog(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.check_jobs.start()

    @tasks.loop(hours=24)
    async def check_jobs(self):
        channel = self.bot.get_channel(CHANNEL_ID)
        if not channel:
            return

        headers = {"Authorization": f"Bearer {API_KEY}"}
        params = {"software": "Houdini", "limit": 5}

        try:
            response = requests.get(API_URL, headers=headers, params=params)
            if response.status_code == 200:
                data = response.json()
                jobs = data.get("jobs", [])
                
                for job in jobs:
                    embed = discord.Embed(
                        title=f"{job['title']} — {job['company']}",
                        url=job['job_url'],
                        color=discord.Color.blue()
                    )
                    embed.add_field(name="Location", value=job['displayLocation'], inline=True)
                    embed.add_field(name="Apply", value=f"[Direct Apply]({job['apply_url']})", inline=False)
                    embed.set_footer(text="Powered by ConnectVFX · connectvfx.app")
                    await channel.send(embed=embed)
        except Exception as e:
            print(f"Error checking jobs: {e}")

    @check_jobs.before_loop
    async def before_check_jobs(self):
        await self.bot.wait_until_ready()