NAME

Webservice::Overleaf::API - Perl client helpers for Overleaf import, Git, and experimental project operations

SYNOPSIS

use Webservice::Overleaf::API;

my $ol = Webservice::Overleaf::API->new;

# Official Open in Overleaf interface
my $url = $ol->open_uri(
    uri           => 'https://example.org/paper.zip',
    engine        => 'lualatex',
    main_document => 'main.tex',
);

# Official Git bridge
say $ol->git_url('0123456789abcdef');
$ol->git_clone('0123456789abcdef', 'paper');

# Undocumented web application interface -- opt in explicitly.
my $web = Webservice::Overleaf::API->new(
    experimental => 1,
    session      => $ENV{OVERLEAF_SESSION},
);

for my $project ($web->projects->all) {
    say $project->name;
}

my $compile = $web->compile(
    '0123456789abcdef',
    resource_path => 'main.tex',
);
$web->download_pdf('0123456789abcdef', compile => $compile, to => 'paper.pdf');

DESCRIPTION

This distribution deliberately separates supported Overleaf integration surfaces from browser-session interfaces that Overleaf does not document as a public API.

The supported side covers the Open in Overleaf import interface and the Overleaf Git bridge. The experimental side uses the same project HTML and compile/download endpoints used by the web application. Those endpoints may change without notice and therefore require experimental => 1.

Dispatch::Fu is used for both public operation dispatch and HTTP response classification. Util::H2O::More is used for compact construction and for objectifying returned project and compile data.

CONSTRUCTOR

new

my $ol = Webservice::Overleaf::API->new(
    base_url     => 'https://www.overleaf.com',
    git_base_url => 'https://git.overleaf.com',
    experimental => 0,
    session      => $ENV{OVERLEAF_SESSION},
    cookie_name  => 'overleaf_session2',
    ua           => $http_tiny_compatible_object,
    git_runner   => sub { ... },
);

ua and git_runner are injectable specifically so callers and the test suite can isolate all network and process execution.

OFFICIAL OVERLEAF INTERFACES

open_uri

Builds an Open in Overleaf URL. Accepts uri or uris, optional name or names, and the documented engine, main_document, and visual_editor features.

open_data

Base64-encodes content into a data URI and returns an Open in Overleaf URL. The default MIME type is application/x-tex; use application/zip for a ZIP project.

open_snippet_form

Returns an object describing a POST form to /docs with a raw snip field. This is useful when embedding an Open in Overleaf button in an application.

project_url

Returns the normal browser/editor URL for a project.

git_url

Returns the Git bridge URL for a project.

git_clone, git_pull, git_push, git_remote_add

Run Git using list-form system, avoiding shell interpolation. Authentication is intentionally left to Git's credential mechanism; this module does not put Overleaf Git authentication tokens on the command line or in remote URLs.

AUTHENTICATION

There are two distinct authentication paths because this module uses two separate Overleaf integration surfaces.

Official Git bridge

Git operations use the official Overleaf Git bridge. For Overleaf Cloud, create a Git authentication token in the Overleaf account settings under Git Integration and let Git use that token as the password for the git user. The same token can be used for the projects accessible to that Overleaf account.

This module deliberately leaves credential storage to Git. Use a Git credential helper rather than embedding the token in a remote URL or passing it on a command line.

Experimental browser-session operations

The experimental project-listing, ZIP, compile, PDF, and compile-output methods use the same authenticated browser session as the Overleaf web application. At present the practical authentication method is to copy the value of the overleaf_session2 cookie from a browser in which you are already logged in.

For Firefox:

  1. Log into https://www.overleaf.com/ normally.

  2. Open Developer Tools with F12 and select Storage.

  3. Open Cookies, select https://www.overleaf.com, and find overleaf_session2.

  4. Copy only the cookie's Value, not the literal overleaf_session2= prefix.

Chrome-family browsers expose the same cookie under Developer Tools, Application, Storage, Cookies.

The copied value can be supplied directly:

my $ol = Webservice::Overleaf::API->new(
    experimental => 1,
    session      => $session_value,
);

or through the environment:

$ENV{OVERLEAF_SESSION} = $session_value;

my $ol = Webservice::Overleaf::API->new(
    experimental => 1,
);

Treat overleaf_session2 like a password. It grants access as the logged-in Overleaf user and must not be committed, logged, pasted into bug reports, or otherwise disclosed.

Session lifetime

As of the Overleaf Cookie Policy last modified 5 August 2026, overleaf_session2 is an authentication cookie with a documented retention period of 5 days. A copied session value should therefore be treated as a short-lived credential and refreshed from the browser when authentication stops working.

The five-day retention period is not a guarantee that a particular copied session will remain valid for exactly five days. Logging out, revocation, rotation, security changes, or other server-side invalidation may make it stop working earlier.

See https://www.overleaf.com/legal for Overleaf's current cookie policy.

EXPERIMENTAL WEB APPLICATION INTERFACE

These methods require both experimental => 1 and an Overleaf session cookie. OVERLEAF_SESSION is used when session is not passed directly. See "AUTHENTICATION" for the current browser-cookie procedure and session lifetime. Treat this cookie like a password and do not commit or log it.

bootstrap

Fetches the project page and obtains the CSRF token required by state-changing web application requests.

projects

Returns the current non-archived, non-trashed projects as a Util::H2O::More objectified array. It understands the current prefetched-project metadata and older metadata shapes used by older/self-hosted Overleaf releases.

project_zip

Downloads a project ZIP. With to => $filename it writes the bytes to that file; otherwise it returns the bytes.

compile

Compiles a project remotely and returns an object containing status, pdf_url, compile_group, clsi_server_id, and output_files.

An optional resource_path requests that a particular TeX file be treated as the root document for the compile.

download_pdf

Compiles and downloads output.pdf, or accepts a previous compile result via compile => $result. With to => $filename it writes the PDF.

download_output

$ol->download_output($compile, 'output.log', to => 'output.log');

Downloads a named compile artifact from a previous compile result.

COMMAND-LINE CLIENT

The distribution includes overleaf, a command-line companion implemented as a modulino in bin/overleaf. It uses Util::H2O::More::Getopt2h2o for option handling and Dispatch::Fu for command routing.

The supported Git and import interfaces are available directly, for example:

overleaf project-url 0123456789abcdef
overleaf git-url 0123456789abcdef
overleaf clone 0123456789abcdef paper
overleaf open-uri https://example.org/paper.zip

The browser-session operations require --experimental. A convenient current workflow is to place only the value of overleaf_session2 in a protected file:

printf '%s\n' 'PASTE_COOKIE_VALUE_HERE' > session.out
chmod 600 session.out

and then run, for example:

overleaf --experimental --session-file ./session.out projects
overleaf --experimental --session-file ./session.out \
    compile 0123456789abcdef
overleaf --experimental --session-file ./session.out \
    --output paper.pdf pdf 0123456789abcdef

The session file is a single line containing only the cookie value. It is not a JSON file, Netscape cookie jar, or name=value pair. The command also accepts OVERLEAF_SESSION or --session, although --session-file avoids placing the credential directly in the process argument list.

Overleaf currently documents a five-day retention period for overleaf_session2, so expect to refresh session.out periodically by copying a fresh cookie value from a logged-in browser. See "AUTHENTICATION" for the caveat that the credential may become invalid earlier.

Run:

overleaf --help

for the complete command reference.

DISPATCH INTERFACE

call

my $projects = $ol->call('projects');
my $git_url  = $ol->call('git_url', $project_id);

Uses Dispatch::Fu to route a static operation name to the corresponding method. Unsupported names throw an exception.

TESTING

The distribution's tests make no live Overleaf requests. The HTTP client and Git runner are injected and mocked so request methods, URLs, headers, compile bodies, error handling, binary downloads, and dispatch behavior are exercised deterministically.

COMPATIBILITY NOTES

Overleaf documents the Open in Overleaf interface and Git integration. It does not document the ordinary project web application's browser endpoints as a stable public API. The experimental implementation is informed by observable web-client behavior and by the open-source olcli project, which tracks these endpoint changes in practice.

SEE ALSO

Dispatch::Fu, Util::H2O::More, HTTP::Tiny, https://www.overleaf.com/devs, https://www.overleaf.com/learn/how-to/Git_integration, https://www.overleaf.com/legal, https://github.com/aloth/olcli

AUTHOR

Brett Estrade <oodler@cpan.org>

LICENSE AND COPYRIGHT

Copyright 2026 Brett Estrade.

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.