# Ruby Integration — RenderPix

**API Endpoint:** `POST https://renderpix.dev/v1/render`

---

## Authentication

Pass your API key in the `X-API-Key` header on every request.

```ruby
API_KEY  = 'rpx_your_api_key'
ENDPOINT = 'https://renderpix.dev/v1/render'
```

---

## Basic Example — HTML to PNG

```ruby
require 'net/http'
require 'json'
require 'uri'

def render_html(html, output_file: 'output.png')
  uri  = URI('https://renderpix.dev/v1/render')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true
  http.read_timeout = 30

  request = Net::HTTP::Post.new(uri.path)
  request['X-API-Key']     = 'rpx_your_api_key'
  request['Content-Type']  = 'application/json'
  request.body = JSON.generate(
    html:   html,
    width:  1200,
    height: 630,
    format: 'png'
  )

  response = http.request(request)

  unless response.code == '200'
    error = JSON.parse(response.body) rescue {}
    raise "RenderPix error #{response.code}: #{error['message'] || response.message}"
  end

  File.binwrite(output_file, response.body)
  puts "Saved to #{output_file}"
end

render_html('<h1 style="font-family:sans-serif;color:#1e293b">Hello, RenderPix!</h1>')
```

---

## Real-World Example — OG Image Generator

```ruby
require 'net/http'
require 'json'
require 'uri'

def generate_og_image(title:, description:, domain:, output_file: 'og.png')
  html = <<~HTML
    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="UTF-8">
      <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body {
          width: 1200px; height: 630px; overflow: hidden;
          font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
          background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
          display: flex; align-items: center; justify-content: center; padding: 80px;
        }
        .card { display: flex; flex-direction: column; gap: 24px; width: 100%; }
        .domain { font-size: 20px; font-weight: 600; color: #38bdf8;
                  text-transform: uppercase; letter-spacing: 2px; }
        h1 { font-size: 72px; font-weight: 800; color: #f1f5f9; line-height: 1.1; }
        p  { font-size: 28px; color: #94a3b8; line-height: 1.5; }
      </style>
    </head>
    <body>
      <div class="card">
        <div class="domain">#{domain}</div>
        <h1>#{title}</h1>
        <p>#{description}</p>
      </div>
    </body>
    </html>
  HTML

  uri  = URI('https://renderpix.dev/v1/render')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  req = Net::HTTP::Post.new(uri.path)
  req['X-API-Key']    = 'rpx_your_api_key'
  req['Content-Type'] = 'application/json'
  req.body = JSON.generate(html: html, width: 1200, height: 630, format: 'png')

  res = http.request(req)
  raise "Render failed (#{res.code}): #{JSON.parse(res.body)['message'] rescue res.message}" unless res.code == '200'

  File.binwrite(output_file, res.body)
  output_file
end

# Usage
file = generate_og_image(
  title:       'Build Faster with RenderPix',
  description: 'HTML to image in one API call. No puppeteer, no headless browser.',
  domain:      'renderpix.dev'
)
puts "OG image saved: #{file}"
```

---

## Response Handling

A successful render returns the image binary directly.

```ruby
response = http.request(request)

if response.code == '200'
  content_type = response['Content-Type'] # 'image/png'
  image_bytes  = response.body            # binary string
  File.binwrite('output.png', image_bytes)
end
```

---

## Error Handling

```ruby
require 'net/http'
require 'json'

def render_safe(html)
  uri  = URI('https://renderpix.dev/v1/render')
  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl     = true
  http.open_timeout = 10
  http.read_timeout = 30

  req = Net::HTTP::Post.new(uri.path)
  req['X-API-Key']    = 'rpx_your_api_key'
  req['Content-Type'] = 'application/json'
  req.body = JSON.generate(html: html, width: 1200, height: 630)

  begin
    res = http.request(req)
  rescue Net::OpenTimeout, Net::ReadTimeout => e
    warn "Network timeout: #{e.message}"
    return nil
  rescue SocketError => e
    warn "Network error: #{e.message}"
    return nil
  end

  error = JSON.parse(res.body) rescue {}

  case res.code
  when '200' then res.body
  when '401' then raise 'Invalid API key — check X-API-Key header'
  when '429' then raise 'Rate limit exceeded — slow down or upgrade plan'
  when '422' then raise "Invalid request: #{error['message']}"
  else raise "Render failed (#{res.code}): #{error['message'] || 'unknown error'}"
  end
end

# Rails — serve image directly from controller
def og_image
  title = params[:title] || 'Untitled'
  html  = "<html><body style='margin:0;background:#0f172a;width:1200px;height:630px;display:flex;align-items:center;justify-content:center'><h1 style='color:#f1f5f9;font-family:sans-serif;font-size:80px'>#{title}</h1></body></html>"

  image = render_safe(html)
  return head :internal_server_error unless image

  send_data image, type: 'image/png', disposition: 'inline'
end
```
