Skip to main content
POST
/
v1
/
files
/
upload
/
{file_id}
/
complete
from retab import Retab
from pathlib import Path

client = Retab()

# Create an upload session, PUT bytes to the signed URL yourself,
# then complete the upload.
invoice_path = Path("invoice.pdf")
session = client.files.create_upload(
    filename=invoice_path.name,
    size_bytes=invoice_path.stat().st_size,
    content_type="application/pdf",
)
mime = client.files.complete_upload(session.file_id)
print(mime.url)  # https://storage.retab.com/...
import { Retab } from "@retab/node";

const client = new Retab({ apiKey: process.env.RETAB_API_KEY });

// Create an upload session, PUT bytes to upload.uploadUrl yourself,
// then complete the upload.
const mime = await client.files.complete_upload((await client.files.create_upload("./invoice.pdf", 1024, "application/pdf")).fileId);
console.log(mime.url); // https://storage.retab.com/...
package main

import (
	"context"
	"fmt"
	"log"

	retab "github.com/retab-dev/retab/clients/go"
)

func ptr[T any](v T) *T { return &v }

func main() {
	ctx := context.Background()

	client, err := retab.NewClient("")
	if err != nil {
		log.Fatal(err)
	}

	// Create an upload session, PUT bytes to upload.UploadURL yourself,
	// then complete the upload.
	upload, err := client.Files.CreateUpload(ctx, &retab.FilesCreateUploadParams{
		Filename:    "invoice.pdf",
		ContentType: ptr("application/pdf"),
		SizeBytes:   1024,
	})
	if err != nil {
		log.Fatal(err)
	}
	mime, err := client.Files.CompleteUpload(ctx, upload.FileID, nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(mime.URL) // https://storage.retab.com/...

	// Lower-level — only when you've handled the PUT yourself.
	// CompleteUpload finalizes a direct-to-storage upload after the
	// bytes have already been written to the signed uploadUrl.
	completed, err := client.Files.CompleteUpload(ctx, "file_a1b2c3d4e5f6", nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(completed.URL)
}
require 'retab'

client = Retab::Client.new(api_key: ENV['RETAB_API_KEY'])

# Lower-level — only when you've handled the PUT yourself.
# complete_upload finalizes a direct-to-storage upload after the
# bytes have already been written to the signed uploadUrl.
completed = client.files.complete_upload(file_id: 'file_a1b2c3d4e5f6')
puts completed.url # https://storage.retab.com/...
use retab::models::CompleteFileUploadRequest;
use retab::resources::files::CompleteUploadParams;
use retab::Retab;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Retab::new(std::env::var("RETAB_API_KEY")?);

    let completed = client
        .files()
        .complete_upload(
            "file_a1b2c3d4e5f6",
            CompleteUploadParams::new(CompleteFileUploadRequest { sha_256: None }),
        )
        .await?;
    println!("{}", completed.url);
    Ok(())
}
<?php
require 'vendor/autoload.php';

use Retab\Client;

$client = new Client(apiKey: getenv('RETAB_API_KEY'));

$result = $client->files()->completeUpload(
    fileId: 'file_6dd6eb00688ad8d1',
);
print_r($result);
using Retab;
using RetabClient = Retab.Retab;

var apiKey = Environment.GetEnvironmentVariable("RETAB_API_KEY")!;
var client = new RetabClient(apiKey);

var result = await client.Files.CompleteUploadAsync("file_6dd6eb00688ad8d1", new FilesCompleteUploadOptions());
Console.WriteLine(result);
import com.retab.RetabClient;

public final class Example {
  public static void main(String[] args) throws Exception {
    RetabClient client = new RetabClient(System.getenv("RETAB_API_KEY"));

    var result = client.files().completeUpload("file_abc123", "abc123");
    System.out.println(result);
  }
}
curl -X POST \
  'https://api.retab.com/v1/files/upload/file_a1b2c3d4e5f6/complete' \
  -H "Authorization: Bearer $RETAB_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{}'
{
  "filename": "invoice.pdf",
  "url": "https://storage.retab.com/file_a1b2c3d4e5f6"
}
Complete a direct-to-storage upload after the file bytes have been written to the signed uploadUrl. Retab verifies that the object exists, matches the expected size from the upload session, and belongs to the authenticated organization. The response is a MIMEData object that can be passed directly to later document requests.
Use client.files.create_upload(...) to request a signed upload URL, PUT the bytes to that URL, then call client.files.complete_upload(...) to receive the durable MIMEData reference.Reach for this endpoint when you want to drive the PUT yourself (e.g. browser-side upload that bypasses your backend) and need to call complete from your server once the bytes have landed.
from retab import Retab
from pathlib import Path

client = Retab()

# Create an upload session, PUT bytes to the signed URL yourself,
# then complete the upload.
invoice_path = Path("invoice.pdf")
session = client.files.create_upload(
    filename=invoice_path.name,
    size_bytes=invoice_path.stat().st_size,
    content_type="application/pdf",
)
mime = client.files.complete_upload(session.file_id)
print(mime.url)  # https://storage.retab.com/...
import { Retab } from "@retab/node";

const client = new Retab({ apiKey: process.env.RETAB_API_KEY });

// Create an upload session, PUT bytes to upload.uploadUrl yourself,
// then complete the upload.
const mime = await client.files.complete_upload((await client.files.create_upload("./invoice.pdf", 1024, "application/pdf")).fileId);
console.log(mime.url); // https://storage.retab.com/...
package main

import (
	"context"
	"fmt"
	"log"

	retab "github.com/retab-dev/retab/clients/go"
)

func ptr[T any](v T) *T { return &v }

func main() {
	ctx := context.Background()

	client, err := retab.NewClient("")
	if err != nil {
		log.Fatal(err)
	}

	// Create an upload session, PUT bytes to upload.UploadURL yourself,
	// then complete the upload.
	upload, err := client.Files.CreateUpload(ctx, &retab.FilesCreateUploadParams{
		Filename:    "invoice.pdf",
		ContentType: ptr("application/pdf"),
		SizeBytes:   1024,
	})
	if err != nil {
		log.Fatal(err)
	}
	mime, err := client.Files.CompleteUpload(ctx, upload.FileID, nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(mime.URL) // https://storage.retab.com/...

	// Lower-level — only when you've handled the PUT yourself.
	// CompleteUpload finalizes a direct-to-storage upload after the
	// bytes have already been written to the signed uploadUrl.
	completed, err := client.Files.CompleteUpload(ctx, "file_a1b2c3d4e5f6", nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(completed.URL)
}
require 'retab'

client = Retab::Client.new(api_key: ENV['RETAB_API_KEY'])

# Lower-level — only when you've handled the PUT yourself.
# complete_upload finalizes a direct-to-storage upload after the
# bytes have already been written to the signed uploadUrl.
completed = client.files.complete_upload(file_id: 'file_a1b2c3d4e5f6')
puts completed.url # https://storage.retab.com/...
use retab::models::CompleteFileUploadRequest;
use retab::resources::files::CompleteUploadParams;
use retab::Retab;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let client = Retab::new(std::env::var("RETAB_API_KEY")?);

    let completed = client
        .files()
        .complete_upload(
            "file_a1b2c3d4e5f6",
            CompleteUploadParams::new(CompleteFileUploadRequest { sha_256: None }),
        )
        .await?;
    println!("{}", completed.url);
    Ok(())
}
<?php
require 'vendor/autoload.php';

use Retab\Client;

$client = new Client(apiKey: getenv('RETAB_API_KEY'));

$result = $client->files()->completeUpload(
    fileId: 'file_6dd6eb00688ad8d1',
);
print_r($result);
using Retab;
using RetabClient = Retab.Retab;

var apiKey = Environment.GetEnvironmentVariable("RETAB_API_KEY")!;
var client = new RetabClient(apiKey);

var result = await client.Files.CompleteUploadAsync("file_6dd6eb00688ad8d1", new FilesCompleteUploadOptions());
Console.WriteLine(result);
import com.retab.RetabClient;

public final class Example {
  public static void main(String[] args) throws Exception {
    RetabClient client = new RetabClient(System.getenv("RETAB_API_KEY"));

    var result = client.files().completeUpload("file_abc123", "abc123");
    System.out.println(result);
  }
}
curl -X POST \
  'https://api.retab.com/v1/files/upload/file_a1b2c3d4e5f6/complete' \
  -H "Authorization: Bearer $RETAB_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{}'
{
  "filename": "invoice.pdf",
  "url": "https://storage.retab.com/file_a1b2c3d4e5f6"
}

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

file_id
string
required

Body

application/json

Body to finalize a file upload, optionally carrying the uploaded content's sha256 checksum for verification.

sha256
string | null

Optional SHA-256 checksum

Pattern: ^[a-fA-F0-9]{64}$

Response

Successful Response

A file represented by its filename and a base64 data url.

filename
string
required

The filename of the file

Examples:

"file.pdf"

"image.png"

"data.txt"

url
string
required

The URL of the file in base64 format

Example:

"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA..."