@marcobarcelos asked for this, and I think others would be interested as well.
In the recently closed issue, I mentioned I had Claude rummage through a xochitl beta binary version with Ghidra to see if it could see what is upcoming in terms of API changes.
It produced an entire research report, but a lot of it is probably noise. But there are some super interesting findings:
Everything below the horizontal line below is copied verbatim from Claude's research report, I haven't looked into any of its findings myself.
The Xochitl binary version is 3.27.1.1451, the beta version of the reMarkable software was 3.27.1.0
URL templates from xochitl 3.27.1 (fmtlib {} format strings)
{}{}/files/{} ← GET/PUT blob (rmapi already uses this shape)
{}{}/files/{}/metadata ← unknown — 404 on every host we tried
{}{}/folders/{} ← unknown — 404 everywhere
{}{}/tree/{} ← unknown — not tried yet
{}/delta ← unknown — 404 everywhere
{}.tectonic.remarkable.com ← regional host template
The first two {} in {}{}/files/{} are presumably <host> + <base-path>. xochitl probably runs them as {host=https://eu.tectonic.remarkable.com}{base=/sync/v3}/files/{hash} — i.e., the same URL we've been hitting.
New rm-* HTTP header family
ASCII strings, embedded as constants:
rm-batch-number rm-expect-version
rm-filename rm-migrate-auth-v2
rm-parent-hash rm-path
rm-recovered-empty-hash rm-recovered-missing-hash
rm-sha256-mismatch rm-sync-id
rm-test-data rm-token-ttl-hint
Of these, rmapi only knows rm-filename (plus rm-token-ttl-hint, which is a response header). Strong candidates for the missing-required ones the server now demands:
rm-expect-version — almost certainly the schema version (3 or 4)
rm-sync-id — probably a per-sync correlation ID
rm-parent-hash — for content-addressed v4 blob lookups
rm-path — full document path (replacing rm-filename?)
rm-migrate-auth-v2 — auth migration flag
URL templates (fmtlib {} style format strings)
/sync/v3/
{}{}/files/{} ← GET blob (same as rmapi)
{}{}/files/{}/metadata ← NEW endpoint rmapi doesn't know about
Source tree leaked via build paths: xofm::libs::sync::core::* and xofm::libs::syncinterface::*. documentsync_1_5.cpp exists — the "1.5" in their terminology equals what rmapi calls sync15/v3.
Other strings of interest
tortoise (UTF-16) — the JWT scope sync:tortoise is real, not just a name
document, collection near tortoise — entity types
xofm::libs::integrations::storage::SyncThirdParty — third-party sync integration class
Discovered endpoint families
A static initializer (e.g. FUN_0046ce90, FUN_0047b8a0 — there are ~70 like it, one per compilation unit that uses sync URLs) registers these URL templates via fmt::format:
"/sync/v3/" + "{}missing" → /sync/v3/missing
"/sync/v3/" + "{}check-files" → /sync/v3/check-files
"/gentree/v1/" + "{}GetEntries"
"/gentree/v1/" + "{}GetFiles"
"/gentree/v1/" + "{}DeleteEntry"
"/gentree/v1/" + "{}EntrySession"
"/gentree/v1/" + "{}PutFile"
"/gentree/v1/" + "{}GetFile" ← the new blob fetch
Plus an unused "rM sync tree" label (a SHA-256 seed for tree hashing — QCryptographicHash::QCryptographicHash(_, 4) = Sha256).
Probe results on these endpoints
| endpoint |
host |
result |
GET /sync/v3/missing |
EU tectonic |
200 {"hashes":[]} — defined; op=GetMissingFiles |
POST /sync/v3/check-files {"files":[hash]} |
EU tectonic |
200 {"missingFiles":[]} — defined; op=CheckFiles |
* /gentree/v1/* |
EU tectonic and legacy |
404 UnknownOperationName — entire namespace 404s on every host we tried |
So:
/sync/v3/missing and /sync/v3/check-files are real, new endpoints exposed on tectonic that we hadn't tried before.
/gentree/v1/* is defined in xochitl beta firmware but does not exist on production ingress. Either: deployed only on staging/internal hosts, gated behind a feature flag we don't have, or routed through an mTLS-protected internal gateway that the device alone can reach.
@marcobarcelos asked for this, and I think others would be interested as well.
In the recently closed issue, I mentioned I had Claude rummage through a xochitl beta binary version with Ghidra to see if it could see what is upcoming in terms of API changes.
It produced an entire research report, but a lot of it is probably noise. But there are some super interesting findings:
Everything below the horizontal line below is copied verbatim from Claude's research report, I haven't looked into any of its findings myself.
The Xochitl binary version is
3.27.1.1451, the beta version of the reMarkable software was3.27.1.0URL templates from xochitl 3.27.1 (fmtlib
{}format strings)The first two
{}in{}{}/files/{}are presumably<host>+<base-path>. xochitl probably runs them as{host=https://eu.tectonic.remarkable.com}{base=/sync/v3}/files/{hash}— i.e., the same URL we've been hitting.New
rm-*HTTP header familyASCII strings, embedded as constants:
Of these, rmapi only knows
rm-filename(plusrm-token-ttl-hint, which is a response header). Strong candidates for the missing-required ones the server now demands:rm-expect-version— almost certainly the schema version (3 or 4)rm-sync-id— probably a per-sync correlation IDrm-parent-hash— for content-addressed v4 blob lookupsrm-path— full document path (replacingrm-filename?)rm-migrate-auth-v2— auth migration flagURL templates (fmtlib
{}style format strings)Source tree leaked via build paths:
xofm::libs::sync::core::*andxofm::libs::syncinterface::*.documentsync_1_5.cppexists — the "1.5" in their terminology equals what rmapi calls sync15/v3.Other strings of interest
tortoise(UTF-16) — the JWT scopesync:tortoiseis real, not just a namedocument,collectionneartortoise— entity typesxofm::libs::integrations::storage::SyncThirdParty— third-party sync integration classDiscovered endpoint families
A static initializer (e.g.
FUN_0046ce90,FUN_0047b8a0— there are ~70 like it, one per compilation unit that uses sync URLs) registers these URL templates viafmt::format:Plus an unused "rM sync tree" label (a SHA-256 seed for tree hashing —
QCryptographicHash::QCryptographicHash(_, 4)=Sha256).Probe results on these endpoints
GET /sync/v3/missing{"hashes":[]}— defined; op=GetMissingFilesPOST /sync/v3/check-files{"files":[hash]}{"missingFiles":[]}— defined; op=CheckFiles* /gentree/v1/*So:
/sync/v3/missingand/sync/v3/check-filesare real, new endpoints exposed on tectonic that we hadn't tried before./gentree/v1/*is defined in xochitl beta firmware but does not exist on production ingress. Either: deployed only on staging/internal hosts, gated behind a feature flag we don't have, or routed through an mTLS-protected internal gateway that the device alone can reach.