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

# Ruby

> Install and use formable, the official Ruby SDK for the Formable API.

[`formable`](https://rubygems.org/gems/formable) is the official Ruby SDK for the Formable API (v1). It covers templates, signature requests, redlining, and billing.

* Faraday HTTP client (injectable)
* Keyword arguments and snake\_case method names
* Ruby 3.1+

Source code is on [GitHub](https://github.com/FormableDocs/formable-ruby).

## Installation

<CodeGroup>
  ```ruby Gemfile theme={null}
  gem "formable"
  ```

  ```bash bundle theme={null}
  bundle add formable
  ```

  ```bash gem theme={null}
  gem install formable
  ```
</CodeGroup>

## Initialize the client

Pass your API key from [Settings](https://app.formabledocs.com/settings). It's sent as a bearer token on every request.

```ruby theme={null}
require "formable"

formable = Formable.new(api_key: ENV.fetch("FORMABLE_API_KEY"))
```

## Templates

Upload a document to create a reusable template, then mint edit URLs to place fields in the embedded editor. See the [embedded templates walkthrough](/walkthroughs/embedded-templates). `file` accepts a path, binary string, or IO. Pass `filename:` when `file` is not a path.

```ruby theme={null}
result = formable.templates.create(
  file: "nda.docx",
  signer_roles: [
    { name: "Client", order: 0 },
    { name: "Witness", order: 1 }
  ]
)

template_id = result["templateId"]

# Mint a fresh edit URL later (expires after 1 day)
edit = formable.templates.create_edit_url(template_id)
```

## Signature requests

Send a template for signing by email, or embed the signing experience in your product. See the [embedded signing walkthrough](/walkthroughs/embedded-signing).

```ruby theme={null}
# Formable emails each signer a signing link
request = formable.signature_requests.create(
  template_id: template_id,
  signers: [
    { email: "jane@example.com", name: "Jane Doe", role: "Client" },
    { email: "bob@example.com", name: "Bob Smith", role: "Witness" }
  ]
)

# Embedded flow: mint signing URLs to embed in an iframe yourself
embedded = formable.signature_requests.create_embedded(
  template_id: template_id,
  signers: [{ email: "jane@example.com", name: "Jane Doe", role: "Client" }],
  test_mode: true
)

signer = embedded["signers"].first
signing = formable.signature_requests.create_signing_url(
  signer["recipientSignatureId"]
)

# Track progress
current = formable.signature_requests.get(embedded["signatureRequestId"])
all_requests = formable.signature_requests.list(
  updated_since: Time.utc(2026, 1, 1)
)
events = formable.signature_requests.get_events(embedded["signatureRequestId"])

# Download the signed document once completed
envelope = formable.signature_requests.get_signed_envelope(
  embedded["signatureRequestId"]
)
```

<Note>
  `get_signed_envelope` raises a `409` until the document is complete. Wait for the [`document_completed`](/webhooks/events#document_completed) webhook, or poll `get` until `status` is `Completed`.
</Note>

## Redline requests

Run turn-based contract negotiation before signing. See the [redlining walkthrough](/walkthroughs/redlining).

```ruby theme={null}
created = formable.redline_requests.create(
  template_id: template_id,
  members: [
    { email: "us@example.com", display_name: "John Doe", role: "DisclosingParty" },
    { email: "them@example.com", display_name: "Jane Smith", role: "ReceivingParty" }
  ],
  metadata: { subject: "Mutual NDA" }
)

redline_request_id = created["redlineRequestId"]

# Mint a redline URL for a member (embed in an iframe)
url = formable.redline_requests.create_url(redline_request_id, "them@example.com")

# Manage members and track progress
formable.redline_requests.update_members(
  redline_request_id,
  [{ email: "counsel@example.com", display_name: "Counsel", role: "ReceivingCounsel" }]
)
redline = formable.redline_requests.get(redline_request_id)
events = formable.redline_requests.get_events(redline_request_id)
```

## Billing and health

```ruby theme={null}
billing = formable.billing
health = formable.health
```

## Error handling

All non-2xx responses raise a `Formable::Error` with the server's error message, HTTP status, and parsed response body.

```ruby theme={null}
begin
  formable.signature_requests.get("missing-id")
rescue Formable::Error => error
  warn "#{error.status} #{error.message}"
end
```

## Configuration

The client takes an API key, then optional `base_url`, `timeout`, and Faraday `connection` arguments.

```ruby theme={null}
require "faraday"

formable = Formable.new(
  api_key: ENV.fetch("FORMABLE_API_KEY"),
  base_url: "https://api.formabledocs.com/v1",
  timeout: 60,
  connection: Faraday.new { |conn| conn.adapter Faraday.default_adapter }
)
```

| Option       | Description                                               | Default                           |
| ------------ | --------------------------------------------------------- | --------------------------------- |
| `api_key`    | Your Formable API key (sent as a bearer token). Required. | -                                 |
| `base_url`   | Override the API base URL.                                | `https://api.formabledocs.com/v1` |
| `timeout`    | Per-request timeout in seconds.                           | `60`                              |
| `connection` | Custom `Faraday::Connection`.                             | Built-in client with 60s timeout  |

Request hashes accept snake\_case keys (`template_id`, `display_name`, `field_id`). Responses use the API's camelCase field names (`templateId`, `displayName`).

## Next steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    Go from a plain document to a signed PDF in 4 calls.
  </Card>

  <Card title="API reference" icon="code" href="/api-reference/introduction">
    Every endpoint the SDK wraps, with a live playground.
  </Card>
</CardGroup>
