Skip to main content
POST
/
signing-requests
/
create-and-send
@firma-dev/sdk
import { FirmaClient } from "@firma-dev/sdk";

const firma = new FirmaClient({ apiKey: "YOUR_API_KEY" });

const response = await firma.signingRequests.createAndSendSigningRequest({
    "name": "Employment Contract - John Doe",
    "description": "Full-time employment contract",
    "document": "JVBERi0xLjQKJeLjz9MK...",
    "expiration_hours": 168,
    "recipients": [
        {
            "id": "temp_signer_1",
            "first_name": "John",
            "last_name": "Doe",
            "email": "john.doe@example.com",
            "designation": "Signer",
            "order": 1,
            "phone_number": "+1-555-0123",
            "company": "Acme Corp",
            "title": "Software Engineer"
        }
    ],
    "fields": [
        {
            "recipient_id": "temp_signer_1",
            "type": "signature",
            "page": 1,
            "x": 100,
            "y": 500,
            "width": 200,
            "height": 50
        },
        {
            "recipient_id": "temp_signer_1",
            "type": "text",
            "page": 1,
            "x": 100,
            "y": 400,
            "width": 150,
            "height": 30,
            "variable_name": "phone_number",
            "required": true,
            "read_only": true
        }
    ],
    "settings": {
        "use_signing_order": true,
        "send_signing_email": true
    }
});
console.log(response);
curl --request POST \
--url https://api.firma.dev/functions/v1/signing-request-api/signing-requests/create-and-send \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Employment Contract - John Doe",
"description": "Full-time employment contract",
"document": "JVBERi0xLjQKJeLjz9MK...",
"expiration_hours": 168,
"recipients": [
{
"id": "temp_signer_1",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"designation": "Signer",
"order": 1,
"phone_number": "+1-555-0123",
"company": "Acme Corp",
"title": "Software Engineer"
}
],
"fields": [
{
"recipient_id": "temp_signer_1",
"type": "signature",
"page": 1,
"x": 100,
"y": 500,
"width": 200,
"height": 50
},
{
"recipient_id": "temp_signer_1",
"type": "text",
"page": 1,
"x": 100,
"y": 400,
"width": 150,
"height": 30,
"variable_name": "phone_number",
"required": true,
"read_only": true
}
],
"settings": {
"use_signing_order": true,
"send_signing_email": true
}
}
'
import requests

url = "https://api.firma.dev/functions/v1/signing-request-api/signing-requests/create-and-send"

payload = {
"name": "Employment Contract - John Doe",
"description": "Full-time employment contract",
"document": "JVBERi0xLjQKJeLjz9MK...",
"expiration_hours": 168,
"recipients": [
{
"id": "temp_signer_1",
"first_name": "John",
"last_name": "Doe",
"email": "john.doe@example.com",
"designation": "Signer",
"order": 1,
"phone_number": "+1-555-0123",
"company": "Acme Corp",
"title": "Software Engineer"
}
],
"fields": [
{
"recipient_id": "temp_signer_1",
"type": "signature",
"page": 1,
"x": 100,
"y": 500,
"width": 200,
"height": 50
},
{
"recipient_id": "temp_signer_1",
"type": "text",
"page": 1,
"x": 100,
"y": 400,
"width": 150,
"height": 30,
"variable_name": "phone_number",
"required": True,
"read_only": True
}
],
"settings": {
"use_signing_order": True,
"send_signing_email": True
}
}
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.text)
const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Employment Contract - John Doe',
description: 'Full-time employment contract',
document: 'JVBERi0xLjQKJeLjz9MK...',
expiration_hours: 168,
recipients: [
{
id: 'temp_signer_1',
first_name: 'John',
last_name: 'Doe',
email: 'john.doe@example.com',
designation: 'Signer',
order: 1,
phone_number: '+1-555-0123',
company: 'Acme Corp',
title: 'Software Engineer'
}
],
fields: [
{
recipient_id: 'temp_signer_1',
type: 'signature',
page: 1,
x: 100,
y: 500,
width: 200,
height: 50
},
{
recipient_id: 'temp_signer_1',
type: 'text',
page: 1,
x: 100,
y: 400,
width: 150,
height: 30,
variable_name: 'phone_number',
required: true,
read_only: true
}
],
settings: {use_signing_order: true, send_signing_email: true}
})
};

fetch('https://api.firma.dev/functions/v1/signing-request-api/signing-requests/create-and-send', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));
<?php

$curl = curl_init();

curl_setopt_array($curl, [
CURLOPT_URL => "https://api.firma.dev/functions/v1/signing-request-api/signing-requests/create-and-send",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Employment Contract - John Doe',
'description' => 'Full-time employment contract',
'document' => 'JVBERi0xLjQKJeLjz9MK...',
'expiration_hours' => 168,
'recipients' => [
[
'id' => 'temp_signer_1',
'first_name' => 'John',
'last_name' => 'Doe',
'email' => 'john.doe@example.com',
'designation' => 'Signer',
'order' => 1,
'phone_number' => '+1-555-0123',
'company' => 'Acme Corp',
'title' => 'Software Engineer'
]
],
'fields' => [
[
'recipient_id' => 'temp_signer_1',
'type' => 'signature',
'page' => 1,
'x' => 100,
'y' => 500,
'width' => 200,
'height' => 50
],
[
'recipient_id' => 'temp_signer_1',
'type' => 'text',
'page' => 1,
'x' => 100,
'y' => 400,
'width' => 150,
'height' => 30,
'variable_name' => 'phone_number',
'required' => true,
'read_only' => true
]
],
'settings' => [
'use_signing_order' => true,
'send_signing_email' => true
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
package main

import (
"fmt"
"strings"
"net/http"
"io"
)

func main() {

url := "https://api.firma.dev/functions/v1/signing-request-api/signing-requests/create-and-send"

payload := strings.NewReader("{\n \"name\": \"Employment Contract - John Doe\",\n \"description\": \"Full-time employment contract\",\n \"document\": \"JVBERi0xLjQKJeLjz9MK...\",\n \"expiration_hours\": 168,\n \"recipients\": [\n {\n \"id\": \"temp_signer_1\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"designation\": \"Signer\",\n \"order\": 1,\n \"phone_number\": \"+1-555-0123\",\n \"company\": \"Acme Corp\",\n \"title\": \"Software Engineer\"\n }\n ],\n \"fields\": [\n {\n \"recipient_id\": \"temp_signer_1\",\n \"type\": \"signature\",\n \"page\": 1,\n \"x\": 100,\n \"y\": 500,\n \"width\": 200,\n \"height\": 50\n },\n {\n \"recipient_id\": \"temp_signer_1\",\n \"type\": \"text\",\n \"page\": 1,\n \"x\": 100,\n \"y\": 400,\n \"width\": 150,\n \"height\": 30,\n \"variable_name\": \"phone_number\",\n \"required\": true,\n \"read_only\": true\n }\n ],\n \"settings\": {\n \"use_signing_order\": true,\n \"send_signing_email\": true\n }\n}")

req, _ := http.NewRequest("POST", url, payload)

req.Header.Add("Authorization", "<api-key>")
req.Header.Add("Content-Type", "application/json")

res, _ := http.DefaultClient.Do(req)

defer res.Body.Close()
body, _ := io.ReadAll(res.Body)

fmt.Println(string(body))

}
HttpResponse<String> response = Unirest.post("https://api.firma.dev/functions/v1/signing-request-api/signing-requests/create-and-send")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Employment Contract - John Doe\",\n \"description\": \"Full-time employment contract\",\n \"document\": \"JVBERi0xLjQKJeLjz9MK...\",\n \"expiration_hours\": 168,\n \"recipients\": [\n {\n \"id\": \"temp_signer_1\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"designation\": \"Signer\",\n \"order\": 1,\n \"phone_number\": \"+1-555-0123\",\n \"company\": \"Acme Corp\",\n \"title\": \"Software Engineer\"\n }\n ],\n \"fields\": [\n {\n \"recipient_id\": \"temp_signer_1\",\n \"type\": \"signature\",\n \"page\": 1,\n \"x\": 100,\n \"y\": 500,\n \"width\": 200,\n \"height\": 50\n },\n {\n \"recipient_id\": \"temp_signer_1\",\n \"type\": \"text\",\n \"page\": 1,\n \"x\": 100,\n \"y\": 400,\n \"width\": 150,\n \"height\": 30,\n \"variable_name\": \"phone_number\",\n \"required\": true,\n \"read_only\": true\n }\n ],\n \"settings\": {\n \"use_signing_order\": true,\n \"send_signing_email\": true\n }\n}")
.asString();
require 'uri'
require 'net/http'

url = URI("https://api.firma.dev/functions/v1/signing-request-api/signing-requests/create-and-send")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Employment Contract - John Doe\",\n \"description\": \"Full-time employment contract\",\n \"document\": \"JVBERi0xLjQKJeLjz9MK...\",\n \"expiration_hours\": 168,\n \"recipients\": [\n {\n \"id\": \"temp_signer_1\",\n \"first_name\": \"John\",\n \"last_name\": \"Doe\",\n \"email\": \"john.doe@example.com\",\n \"designation\": \"Signer\",\n \"order\": 1,\n \"phone_number\": \"+1-555-0123\",\n \"company\": \"Acme Corp\",\n \"title\": \"Software Engineer\"\n }\n ],\n \"fields\": [\n {\n \"recipient_id\": \"temp_signer_1\",\n \"type\": \"signature\",\n \"page\": 1,\n \"x\": 100,\n \"y\": 500,\n \"width\": 200,\n \"height\": 50\n },\n {\n \"recipient_id\": \"temp_signer_1\",\n \"type\": \"text\",\n \"page\": 1,\n \"x\": 100,\n \"y\": 400,\n \"width\": 150,\n \"height\": 30,\n \"variable_name\": \"phone_number\",\n \"required\": true,\n \"read_only\": true\n }\n ],\n \"settings\": {\n \"use_signing_order\": true,\n \"send_signing_email\": true\n }\n}"

response = http.request(request)
puts response.read_body
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Employment Contract - John Doe",
  "description": "Full-time employment contract",
  "status": "sent",
  "document_url": "https://storage.supabase.co/...",
  "page_count": 3,
  "expiration_hours": 168,
  "settings": {
    "use_signing_order": true,
    "allow_download": true,
    "attach_pdf_on_finish": true,
    "send_signing_email": true,
    "send_finish_email": true,
    "send_expiration_email": true,
    "send_cancellation_email": true,
    "hand_drawn_only": false
  },
  "created_date": "2026-01-12T10:30:00Z",
  "sent_date": "2026-01-12T10:30:00Z",
  "template_id": null,
  "first_signer": {
    "id": "rec456-e89b-12d3-a456-426614174000",
    "name": "John Doe",
    "email": "john.doe@example.com",
    "signing_link": "https://app.firma.dev/signing/rec456-e89b-12d3-a456-426614174000"
  },
  "recipients": [
    {
      "id": "rec456-e89b-12d3-a456-426614174000",
      "first_name": "John",
      "last_name": "Doe",
      "name": "John Doe",
      "email": "john.doe@example.com",
      "designation": "Signer",
      "order": 1
    }
  ],
  "fields": [
    {
      "id": "field123-e89b-12d3-a456-426614174000",
      "type": "signature",
      "page": 1,
      "x": 100,
      "y": 500,
      "width": 200,
      "height": 50,
      "required": true,
      "recipient_id": "rec456-e89b-12d3-a456-426614174000"
    }
  ],
  "credits_remaining": 99
}

Authorizations

Authorization
string
header
required

API key for authentication. Use your API key directly without any prefix (e.g., 'your-api-key'). Bearer prefix is optional but not required.

Body

application/json
name
string
required

Signing request name

Maximum string length: 255
Example:

"Employment Contract - John Doe"

document
string<byte>
required

Base64-encoded PDF or DOCX document (mutually exclusive with template_id and document_id). DOCX files are automatically converted to PDF. Maximum size: 50MB.

Example:

"JVBERi0xLjQKJeLjz9MKMyAwIG9iago8PC9UeXBlIC9QYWdlCi9QYXJlbnQgMSAwIFIKL1Jlc291c..."

description
string

Signing request description

Example:

"Full-time employment contract for Software Engineer position"

template_id
string<uuid>

Template ID to use (mutually exclusive with document and document_id)

Example:

"123e4567-e89b-12d3-a456-426614174000"

expiration_hours
integer
default:168

Hours until signing request expires (default: 168 = 7 days)

Required range: x >= 1
Example:

168

recipients
object[]

Array of recipients. At least one must be a Signer. For document-based: required. For template-based: optional (uses template recipients if omitted). Use template_user_id (preferred) or order (fallback) to match template users.

Minimum array length: 1
fields
object[]

Array of fields to be filled (document-based only)

anchor_tags
object[]

Anchor tags for automatic field placement. Text markers in the PDF are located and converted to positioned fields. The anchor text is removed from the PDF after processing. Fields created from anchor tags are added alongside any manually specified fields. Only available for document-based creation (not template-based).

Maximum array length: 100
reminders
object[]

Array of reminder configurations

settings
object

Signing request settings

document_id
string<uuid>

ID of a previously uploaded document (mutually exclusive with document and template_id). Obtain by calling POST /documents first.

Example:

"123e4567-e89b-12d3-a456-426614174000"

Response

Signing request created and sent successfully

Signing request created and sent

id
string<uuid>
required

Signing request ID

name
string
required

Signing request name

status
enum<string>
required

Always 'sent' for this endpoint

Available options:
sent
description
string | null

Signing request description

document_url
string<uri>

Signed URL to access document

page_count
integer

Number of pages in document

expiration_hours
integer

Hours until expiration

settings
object

Settings returned by the signing request list and detail endpoints. Templates use the TemplateSettings schema (no identity fields).

created_date
string<date-time>
sent_date
string<date-time>

When request was sent

template_id
string<uuid> | null
first_signer
object

Details of the first signer who received the email

recipients
object[]

All recipients with real UUIDs

fields
object[]

All fields with real recipient UUIDs

credits_remaining
integer

Company credits remaining after deduction