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

# Ruby SDK

> The official `dragdropdo-sdk` gem provides a high‑level interface to the D3 Business API. 

## Installation

Add this line to your application's Gemfile:

```ruby theme={null}
gem 'dragdropdo-sdk'
```

And then execute:

```bash theme={null}
bundle install
```

Or install it yourself as:

```bash theme={null}
gem install dragdropdo-sdk
```

## Quick start

```ruby theme={null}
require 'dragdropdo_sdk'

# Initialize the client
client = DragdropdoSdk::Dragdropdo.new(
  api_key: 'your-api-key-here',
  base_url: 'https://api.dragdropdo.com', # Optional, defaults to https://api.dragdropdo.com
  timeout: 30000 # Optional, defaults to 30000ms
)

# Upload a file
upload_result = client.upload_file(
  file: '/path/to/document.pdf',
  file_name: 'document.pdf',
  mime_type: 'application/pdf'
)

puts "File key: #{upload_result[:file_key]}"
```

## Initialization

```ruby theme={null}
DragdropdoSdk::Dragdropdo.new(api_key:, base_url: nil, timeout: 30000, headers: {})
```

**Parameters:**

* `api_key` (**required**) – your D3 API key.
* `base_url` (optional) – API base URL, default: `https://api.dragdropdo.com`.
* `timeout` (optional) – request timeout in ms, default: `30000`.
* `headers` (optional) – additional headers to send with every request.

## File upload

```ruby theme={null}
upload_file(file:, file_name:, mime_type: nil, parts: nil, on_progress: nil)
```

**Parameters:**

* `file` (**required**) – file path string.
* `file_name` (**required**) – original file name.
* `mime_type` (optional) – MIME type (auto‑detected if omitted).
* `parts` (optional) – number of upload parts (auto‑calculated).
* `on_progress` (optional) – progress callback (Proc).

Example:

```ruby theme={null}
result = client.upload_file(
  file: '/path/to/file.pdf',
  file_name: 'document.pdf',
  mime_type: 'application/pdf',
  on_progress: ->(progress) { puts "Upload: #{progress[:percentage]}%" }
)
```

## Supported operations

```ruby theme={null}
check_supported_operation(ext:, action: nil, parameters: nil)
```

**Parameters:**

* `ext` (**required**) – file extension (e.g. `pdf`, `jpg`).
* `action` (optional) – specific action (`convert`, `compress`, ...).
* `parameters` (optional) – parameters to validate (e.g. `{ convert_to: 'png' }`).

Examples:

```ruby theme={null}
# Get available actions for PDF
actions = client.check_supported_operation(ext: 'pdf')
puts actions[:available_actions]

# Check if convert to PNG is supported
supported = client.check_supported_operation(
  ext: 'pdf',
  action: 'convert',
  parameters: { convert_to: 'png' }
)
puts "Supported: #{supported[:supported]}"
```

## Create operations

```ruby theme={null}
create_operation(action:, file_keys:, parameters: nil, notes: nil)
```

**Parameters:**

* `action` (**required**) – `"convert" | "compress" | "merge" | "zip" | "lock" | "unlock" | "reset_password"`.
* `file_keys` (**required**) – array of file keys from upload.
* `parameters` (optional) – action‑specific parameters.
* `notes` (optional) – user metadata.

Examples:

```ruby theme={null}
# Convert PDF to PNG
client.create_operation(
  action: 'convert',
  file_keys: [upload_result[:file_key]],
  parameters: { convert_to: 'png' },
  notes: { userId: 'user-123' }
)

# Compress
client.create_operation(
  action: 'compress',
  file_keys: [upload_result[:file_key]],
  parameters: { compression_value: 'recommended' }
)
```

### Convenience helpers

The client exposes shorthand helpers:

```ruby theme={null}
client.convert(file_keys:, convert_to:, notes: nil)
client.compress(file_keys:, compression_value: 'recommended', notes: nil)
client.merge(file_keys:, notes: nil)
client.zip(file_keys:, notes: nil)
client.lock_pdf(file_keys:, password:, notes: nil)
client.unlock_pdf(file_keys:, password:, notes: nil)
client.reset_pdf_password(file_keys:, old_password:, new_password:, notes: nil)
```

## Status & polling

```ruby theme={null}
get_status(main_task_id:, file_key: nil)
poll_status(main_task_id:, file_key: nil, interval: 2000, timeout: 300000, on_update: nil)
```

**`get_status` keyword arguments** (conceptually `StatusOptions`):

* `main_task_id` (**required**) – main task ID from `create_operation` / convenience helpers.
* `file_key` (optional) – when set, requests status for that specific input file.

**`poll_status` keyword arguments** (extends the same inputs with polling fields):

* `main_task_id` (**required**), `file_key` (optional) – as for `get_status`.
* `interval` (optional) – milliseconds between polls, default `2000`.
* `timeout` (optional) – maximum total polling time in milliseconds, default `300000` (5 minutes).
* `on_update` (optional) – proc/lambda receiving the status hash after each successful fetch.

Examples:

```ruby theme={null}
# Single status fetch
status = client.get_status(main_task_id: 'task-123')

# Poll until completion
final_status = client.poll_status(
  main_task_id: 'task-123',
  interval: 2000,
  timeout: 300000,
  on_update: ->(status) { puts "Status: #{status[:operation_status]}" }
)
```

## Complete workflow example

```ruby theme={null}
require 'dragdropdo_sdk'

def process_file
  client = DragdropdoSdk::Dragdropdo.new(
    api_key: ENV['D3_API_KEY'],
    base_url: 'https://api.dragdropdo.com'
  )

  begin
    # 1. Upload
    upload_result = client.upload_file(
      file: './document.pdf',
      file_name: 'document.pdf'
    )

    # 2. Check support
    supported = client.check_supported_operation(
      ext: 'pdf',
      action: 'convert',
      parameters: { convert_to: 'png' }
    )
    unless supported[:supported]
      raise 'Convert to PNG is not supported'
    end

    # 3. Create operation
    operation = client.convert(
      file_keys: [upload_result[:file_key]],
      convert_to: 'png',
      notes: { userId: 'user-123', source: 'api' }
    )

    # 4. Poll
    status = client.poll_status(
      main_task_id: operation[:main_task_id],
      interval: 2000
    )

    if status[:operation_status] == 'completed'
      status[:files_data].each do |file|
        puts "Download: #{file[:download_link]}"
      end
    end
  rescue DragdropdoSdk::D3APIError => e
    puts "API Error (#{e.status_code}): #{e.message}"
  rescue DragdropdoSdk::D3ValidationError => e
    puts "Validation Error: #{e.message}"
  rescue StandardError => e
    puts "Error: #{e.message}"
  end
end

process_file
```
