> ## Documentation Index
> Fetch the complete documentation index at: https://docs.outcryai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

# Quickstart Guide

Get started with Outcry AI in under 5 minutes. This guide will walk you through authentication, adding credits, and making your first API requests.

## Prerequisites

* An Outcry AI account ([sign up here](https://www.outcryai.com/register))
* Node.js 16+ or Python 3.8+ installed
* 5 minutes of your time

## Step 1: Get Your API Key

<Steps>
  <Step title="Log in to your dashboard">
    Navigate to [outcryai.com](https://www.outcryai.com) and log in to your account.
  </Step>

  <Step title="Generate an API key">
    Go to **Settings > API Keys** and click **Create New Key**.

    Give your key a name (e.g., "Production Key") and select the scopes you need:

    * `video:write` - Create videos
    * `video:read` - Check video status
    * `chat:write` - Create chat completions
    * `chat:read` - Retrieve chat history
  </Step>

  <Step title="Save your key securely">
    Your API key will be shown **only once**. Copy it and store it securely:

    ```
    oc_live_abc123def456...
    ```

    **Never commit API keys to version control!** Use environment variables instead.
  </Step>
</Steps>

## Step 2: Add Credits to Your Account

All API usage is prepaid. Add credits to your account before making requests:

1. Go to **Billing > Add Credits**
2. Select a credit bundle:
   * **Starter**: 4 credits (\$10) - Good for 3-8 videos
   * **Popular**: 11 credits (\$25, +1 bonus)
   * **Power**: 22.5 credits (\$50, +2.5 bonus)
   * **Creator**: 50 credits (\$100, +10 bonus)
3. Complete payment via Stripe or crypto wallet

**Credit Pricing:**

* Videos: 0.5 - 9 credits per video (based on model, duration, resolution)
* Chat/Text: \~0.03 credits per 1,000 tokens (\$0.08 per 1K tokens)

## Step 3: Install the SDK

<CodeGroup>
  ```bash npm theme={null}
  npm install openai
  ```

  ```bash pnpm theme={null}
  pnpm add openai
  ```

  ```bash python theme={null}
  pip install openai
  ```
</CodeGroup>

Yes, you read that right - just install the official OpenAI SDK! Outcry AI is 100% OpenAI-compatible.

## Step 4: Set Up Your Environment

Create a `.env` file (or `.env.local` for Next.js):

```bash theme={null}
OUTCRY_API_KEY=oc_live_abc123def456...
```

**Security Tip**: Never hardcode API keys in your source code. Always use environment variables.

## Step 5: Make Your First Request

### Generate an Activist Video

<CodeGroup>
  ```typescript TypeScript theme={null}
  import OpenAI from 'openai';

  // Initialize client - just change the baseURL!
  const client = new OpenAI({
    apiKey: process.env.OUTCRY_API_KEY,
    baseURL: 'https://api.outcryai.com/v1'
  });

  async function generateVideo() {
    console.log('Creating video...');

    const video = await client.videos.create({
      model: 'sora-2',
      prompt: 'Activists marching for climate justice with banners',
      seconds: '8',  // STRING: "4", "8", or "12"
      size: '1280x720'  // Resolution in pixels
    });

    console.log(`Video ID: ${video.id}`);
    console.log(`Status: ${video.status}`);

    // Poll for completion
    while (video.status === 'queued' || video.status === 'in_progress') {
      await new Promise(resolve => setTimeout(resolve, 5000)); // Wait 5 seconds

      const updated = await client.videos.retrieve(video.id);
      console.log(`Status: ${updated.status} (${updated.progress}%)`);

      if (updated.status === 'completed') {
        console.log(`Video URL: ${updated.url}`);
        break;
      }

      if (updated.status === 'failed') {
        console.error(`Video failed: ${updated.error}`);
        break;
      }
    }
  }

  generateVideo();
  ```

  ```python Python theme={null}
  from openai import OpenAI
  import time
  import os

  # Initialize client - just change the base_url!
  client = OpenAI(
      api_key=os.environ.get("OUTCRY_API_KEY"),
      base_url="https://api.outcryai.com/v1"
  )

  def generate_video():
      print("Creating video...")

      video = client.videos.create(
          model="sora-2",
          prompt="Activists marching for climate justice with banners",
          seconds="8",  # STRING: "4", "8", or "12"
          size="1280x720"  # Resolution in pixels
      )

      print(f"Video ID: {video.id}")
      print(f"Status: {video.status}")

      # Poll for completion
      while video.status in ['queued', 'in_progress']:
          time.sleep(5)  # Wait 5 seconds

          updated = client.videos.retrieve(video.id)
          print(f"Status: {updated.status} ({updated.progress}%)")

          if updated.status == 'completed':
              print(f"Video URL: {updated.url}")
              break

          if updated.status == 'failed':
              print(f"Video failed: {updated.error}")
              break

  generate_video()
  ```

  ```bash curl theme={null}
  # Create video
  curl https://api.outcryai.com/v1/videos \
    -H "Authorization: Bearer oc_live_abc123def456..." \
    -H "Content-Type: application/json" \
    -d '{
      "model": "sora-2",
      "prompt": "Activists marching for climate justice with banners",
      "seconds": "8",
      "size": "1280x720"
    }'

  # Response:
  # {
  #   "id": "video_abc123",
  #   "object": "video",
  #   "created": 1730634060,
  #   "model": "sora-2",
  #   "status": "queued",
  #   "progress": 0,
  #   "url": null
  # }

  # Check status (poll every 5 seconds)
  curl https://api.outcryai.com/v1/videos/video_abc123 \
    -H "Authorization: Bearer oc_live_abc123def456..."

  # Response when complete:
  # {
  #   "id": "video_abc123",
  #   "object": "video",
  #   "created": 1730634060,
  #   "model": "sora-2",
  #   "status": "completed",
  #   "progress": 100,
  #   "url": "https://pub-....r2.dev/videos/..."
  # }
  ```
</CodeGroup>

**Notes:**

* Videos take \~60-90 seconds to generate
* `seconds` must be a STRING ("4", "8", or "12"), not a number
* `size` is pixel dimensions, not aspect ratio
* Poll every 5 seconds - don't hammer the API!

### Chat with Theory of Change

<CodeGroup>
  ```typescript TypeScript theme={null}
  import OpenAI from 'openai';

  const client = new OpenAI({
    apiKey: process.env.OUTCRY_API_KEY,
    baseURL: 'https://api.outcryai.com/v1'
  });

  async function chat() {
    const completion = await client.chat.completions.create({
      model: 'grok-2',
      messages: [
        { role: 'user', content: 'How can I organize a grassroots climate campaign?' }
      ],
      // Optional: Set Theory of Change position
      // @ts-ignore - Custom vendor extension
      'x-theory-position': { x: -0.5, y: -0.3 } // Voluntarist approach
    });

    console.log(completion.choices[0].message.content);
  }

  chat();
  ```

  ```python Python theme={null}
  from openai import OpenAI
  import os

  client = OpenAI(
      api_key=os.environ.get("OUTCRY_API_KEY"),
      base_url="https://api.outcryai.com/v1"
  )

  def chat():
      completion = client.chat.completions.create(
          model="grok-2",
          messages=[
              {"role": "user", "content": "How can I organize a grassroots climate campaign?"}
          ],
          # Optional: Set Theory of Change position
          extra_body={
              "x-theory-position": {"x": -0.5, "y": -0.3}  # Voluntarist approach
          }
      )

      print(completion.choices[0].message.content)

  chat()
  ```

  ```bash curl theme={null}
  curl https://api.outcryai.com/v1/chat/completions \
    -H "Authorization: Bearer oc_live_abc123def456..." \
    -H "Content-Type: application/json" \
    -d '{
      "model": "grok-2",
      "messages": [
        {"role": "user", "content": "How can I organize a grassroots climate campaign?"}
      ],
      "x-theory-position": {"x": -0.5, "y": -0.3}
    }'
  ```
</CodeGroup>

**Theory of Change Position:**

* `x` axis: -1 (Subjective) to +1 (Objective)
* `y` axis: -1 (Material) to +1 (Spiritual)
* Examples:
  * `{x: -0.8, y: -0.6}` - Strong voluntarist (grassroots organizing)
  * `{x: 0.7, y: -0.5}` - Structuralist (policy/systems focus)
  * `{x: 0, y: 0}` - Balanced approach

Learn more in the [Theory of Change Guide](/guides/theory-of-change).

## Step 6: Handle Errors Gracefully

Always wrap API calls in try-catch blocks:

<CodeGroup>
  ```typescript TypeScript theme={null}
  try {
    const video = await client.videos.create({
      model: 'sora-2',
      prompt: 'Activist rally',
      seconds: '8',
      size: '1280x720'
    });
    console.log(`Video created: ${video.id}`);
  } catch (error: any) {
    if (error.status === 402) {
      console.error('Insufficient credits. Please add more credits to your account.');
    } else if (error.status === 429) {
      console.error('Rate limit exceeded. Please slow down.');
    } else if (error.status === 400) {
      console.error(`Validation error: ${error.message}`);
    } else {
      console.error(`API error: ${error.message}`);
    }
  }
  ```

  ```python Python theme={null}
  try:
      video = client.videos.create(
          model="sora-2",
          prompt="Activist rally",
          seconds="8",
          size="1280x720"
      )
      print(f"Video created: {video.id}")
  except Exception as e:
      if hasattr(e, 'status_code'):
          if e.status_code == 402:
              print("Insufficient credits. Please add more credits to your account.")
          elif e.status_code == 429:
              print("Rate limit exceeded. Please slow down.")
          elif e.status_code == 400:
              print(f"Validation error: {e}")
          else:
              print(f"API error: {e}")
      else:
          print(f"Unknown error: {e}")
  ```
</CodeGroup>

Common status codes:

* **400** - Bad request (invalid parameters)
* **401** - Invalid API key
* **402** - Insufficient prepaid balance
* **403** - Missing required scope
* **429** - Rate limit exceeded
* **500** - Server error

See the [Error Handling Guide](/guides/error-handling) for complete details.

## Next Steps

<CardGroup cols={2}>
  <Card title="Authentication Guide" icon="key" href="/guides/authentication">
    Learn about API keys, scopes, and security best practices
  </Card>

  <Card title="Video API Reference" icon="video" href="/api/videos">
    Complete documentation for video generation endpoints
  </Card>

  <Card title="Webhooks Guide" icon="webhook" href="/guides/webhooks">
    Set up real-time notifications for video completions
  </Card>

  <Card title="Theory of Change" icon="compass" href="/guides/theory-of-change">
    Understand how to align AI outputs with your strategy
  </Card>
</CardGroup>

## Production Checklist

Before going to production:

* [ ] Store API keys in environment variables (never hardcode)
* [ ] Implement error handling for all API calls
* [ ] Set up webhooks for video completions (don't poll)
* [ ] Add retry logic for transient errors (429, 500)
* [ ] Monitor your credit balance
* [ ] Set up alerts for low credit balance
* [ ] Test rate limiting behavior
* [ ] Implement exponential backoff for retries

Ready to build? Explore the full [API Reference](/api/videos) or read the [Authentication Guide](/guides/authentication).
