CAR / CORE / PIVO · Organizations, research journals and API

Every person receives CAR and every organization CORE automatically when the account is created. Organization accounts issue PIVO for articles and other outputs through Manage PIVO or the authenticated API.

Open identifier and journal API guide · OpenAPI JSON · Projects, URLs, deletion and eWeb export

Read how CAR, CORE, PIVO and journal integration work

<!-- Author: PB <pavel.bartos.pb@gmail.com> -->

People, organizations and identifiers

Profile cards, short URLs and sign-in

A person has a public profile URL such as

https://update.estudium.eu/CAR-0000-0002; an organization uses, for example,

https://update.estudium.eu/CORE-00001. These IDs are examples: use the identifier

assigned to the actual account. Changing the display name does not change the

identifier or profile URL. Profiles require an active account and publication consent.

An article or book with PIVO uses https://update.estudium.eu/PIVO-0-0000-0001.

A publication without PIVO uses its existing 32-character publication ID directly

after the domain. Copy its Open link from the catalog or profile. A short URL

does not issue PIVO; only organizations can issue it. Legacy

/profile.php?id=…, /pivo.php?id=… and /article.php?id=… links redirect with

HTTP 301. Canonical URLs, sitemap.xml and the publication feed.xml use the new

addresses. Software keeps /login/project, for example /admin/eweb-server.

To sign in, enter your login, CAR or CORE and the account's normal password.

CAR/CORE matching is case-insensitive. These public identifiers do not replace a

password; blocked accounts cannot sign in. New passwords require at least 10 characters.

Under My account → My public profile, drop a photo or logo onto the upload

area, or choose a file with the file picker. Use one PNG, JPEG or WebP up to

512 KiB and 4000 × 4000 pixels. A preview appears immediately; click

Save profile to commit it. Removing the image also requires saving. File

errors appear beside the upload area, and the server validates the actual image.

The public card has a compact header, contacts and identifiers, education or

business category, affiliations and a filled-in CV. Optional contacts such as

email and phone appear only when their publication boxes are checked.

Organization logos are displayed without cropping. Empty CV sections are omitted.

Author projects / Organization projects combines public software, books,

articles and other publications associated with the account. Use the category

buttons to filter. All cards are present in the initial HTML for search and

indexing. Choose the publication type when adding it to your account or PIVO.

The catalog merges recognized duplicate works. A matching author name alone does

not attach another account's publication to your profile: add it to your own

publications, optionally referencing an existing PIVO. Private and archived

software projects are excluded from the public portfolio.

Quick start for research journals

CAR identifies a person, CORE identifies an organization/publisher, and PIVO

identifies a published output. CAR and CORE are allocated **when the account is

created**, both through public registration and administrator account creation.

People receive CAR and organizations CORE regardless of role or profile consent.

Existing accounts missing their identifier are repaired on the next request.

Account identifiers are automatic and immutable.

  • Register a Company / school / organization account for the journal or

publisher. Enter the public publisher name, logo, registration number,

business category and existing ROR if applicable. CORE is allocated immediately.

If an administrator supplied a temporary password, change it first.

  • Authors create personal accounts with CAR and may add ORCID. They can request

affiliation through My organizations; the publisher approves it in

Organization members. Membership and project collaboration do not grant

PIVO issuing rights: only the organization account or its server API key issues PIVO.

  • After editorial approval, sign in as the organization and open

Manage PIVO → Register PIVO. Enter title, semicolon-separated authors,

publication month/year, abstract, keywords, and a public article URL or an owned PDF.

Add journal name, ISSN, volume, issue, pages and license. A publisher can serve

several journals, distinguished by the journal and issn metadata.

  • Confirm publication to allocate the next global sequential PIVO. The issuer

is recorded in issuer_core; journals do not reserve a prefix or restart the

sequence. The registry stores the identifier, publisher, metadata and revision.

  • Save the returned PIVO and stable URL in the editorial system, article page

and PDF. Authors can link that existing PIVO from their own publication entry;

they do not issue another identifier. The catalogue groups duplicate records.

  • When a PDF moves, update the same PIVO URL. For corrections, submit its current

revision and complete metadata. Use withdraw with a reason for retractions;

the public status page and reserved identifier remain available.

Editorial system API integration

From the organization account, open Manage PIVO → API keys → Create API key.

Store the secret on your editorial server, never in visitor JavaScript. This

example expects the key in the PIVO_TOKEN environment variable.

curl --request POST 'https://update.estudium.eu/pivo-api.php' \
  --header "Authorization: Bearer $PIVO_TOKEN" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: journal-2026-article-0042' \
  --data '{"action":"create","metadata":{"title":"Example journal article","authors":"Novak, Jan; Smith, Eva","publication_date":"2026-09","abstract":"A complete public abstract of the article.","keywords":"education; research; learning analytics","type":"article","journal":"Example Research Journal","issn":"0378-5955","volume":"4","issue":"2","pages":"10-21","publisher":"Example Publisher","url":"https://journal.example.org/articles/42","language":"en","license":"CC BY 4.0"}}'

Example response (abbreviated; the actual identifier is allocated by the registry):

{"ok":true,"created":true,"record":{"id":"PIVO-0-0000-0001","sequence":1,"issuer_core":"CORE-00001","revision":1,"status":"published","url":"https://update.estudium.eu/pivo.php?id=PIVO-0-0000-0001"}}

Save record.id, record.url and record.revision in the editorial database.

After a timeout, retry the same metadata and Idempotency-Key to retrieve the

already allocated ID. A new article needs a different key. Public lookup is

GET /pivo-api.php?id=PIVO-0-0000-0001. Send updates or withdrawals as POST to

the same endpoint using action: update or action: withdraw. Full examples

and response codes follow below.

eUpdate does not automatically insert IDs into external editorial systems or

modify their PDFs. OJS and other journal platforms need a server integration

that calls this API after publication and stores its response. PIVO is not a

Crossref/DataCite DOI; issuing it does not imply peer review or external indexing.

Enter keywords as research; education; learning analytics. A semicolon or Enter

creates a chip; pasted semicolon lists are split immediately. Remove a chip with

its cross button. Multiword phrases stay together. The API accepts the same

semicolon-separated string or an array of strings. Commas within a phrase are

preserved. At most 30 keywords of up to 100 characters are accepted; empty and

exact duplicate entries are ignored.

Registration offers Person or Company / school / organization. Organizations

have a name, logo, category, registration ID (ICO or another scheme), country,

legal form, address, description, projects, modules, collaborators and publications.

The account type is fixed after registration; create a separate organization account.

The login is a technical sign-in name; the public name may contain spaces and Unicode.

Contact email remains private unless its disclosure is enabled. Other completed

profile fields are public while public-profile consent is active.

CAR, CORE, ORCID and ROR

CAR (Czech Academic Researcher) identifies a person: CAR-0000-0001.

CORE (Czech Organization for Research Entities) identifies an organization: CORE-00001.

PIVO (Persistent Index of Verified Outputs) identifies an output: PIVO-0-0000-0001.

Each independent sequence starts at 1, then 2, 3, 4… Integers are encoded as padded

base36 (0–9, A–Z): 9 → 00009, 10 → 0000A. CAR has 8 characters, CORE 5, PIVO 9.

Hyphens only group characters; the first PIVO character is part of the sequence,

not a publisher prefix. Capacities including unused zero are 36^8 = 2,821,109,907,456;

36^5 = 60,466,176; 36^9 = 101,559,956,668,416. Allocation is global within this

installation, serialized by a database lock and committed transactionally. IDs

never change or become available for reuse after account deletion. Existing person

accounts receive CAR automatically on the first request after upgrading.

Find CAR/CORE in the community or resolve /identity.php?id=CAR-0000-0001.

Only public profile cards are revealed; a deleted account returns HTTP 410.

Enter an existing ORCID for a person or an organization's contact person.

ROR denotes an organization; people may enter their related institution's ROR.

Examples: https://orcid.org/0000-0002-1825-0097, https://ror.org/02mhbdp94.

Format and checksums are validated; eUpdate does not issue ORCID/ROR or verify

external account ownership. Specifications:

ORCID,

ROR.

Organization membership

A person requests membership by organization login or email in My organizations.

Multiple organizations are supported. The organization sees requests and members

in Organization members. Membership approval and project collaboration are

separate actions. Granting collaboration gives access to all organization projects;

removal or leaving immediately revokes it. A pending request or a ROR reference

does not grant access. Accepted affiliations appear on a person's public card only

when the related organization also has a public profile.

Publications and PDF

Both account types support title, authors, year, type, publisher, ISBN, ISSN, DOI,

language, license, abstract, output URL, Google Scholar URL and an existing PIVO ID.

ISBN and ISSN include checksum validation. DOI is recorded, not registered.

PDF uploads are chunked, at most 20 MiB per file and 500 MiB per account. Incomplete

and unattached files stay private. A completed PDF becomes downloadable when attached

to a consenting public profile or a published PIVO record. PDF is served as an

attachment and never executed on the server; format checks are not malware scanning.

Use PDF storage to remove unused or incomplete files. Detach profile files and

save first. PIVO attachments are protected against deletion. Publish only material

you are authorized to share and omit private personal data.

Public PIVO catalogue and API

/pivo.php is public and searchable with pagination. Every record has a permanent

landing page /pivo.php?id=PIVO-0-0000-0001, JSON and sitemap entry. Public profiles

use Person/Organization structured data; records use CreativeWork/ScholarlyArticle.

Search result pages are not indexed; publicly linked PDFs can be indexed.

Organizations issue PIVO through Manage PIVO or the API. Required metadata:

title, authors, publication month/year, abstract, keywords, and an HTTP/HTTPS target URL or an owned uploaded PDF.

The issuer attests the metadata; the registry name **does not imply peer review or

scientific quality verification**. PIVO is an eUpdate registry, not DOI, Crossref or

DataCite. Persistence depends on continued operation of update.estudium.eu.

Metadata and target URLs can change, but the ID is immutable. Revisions are retained.

Withdrawal requires a reason and is irreversible; the public landing page becomes

a tombstone. Deleting the issuer account does not delete PIVO. Do not register

metadata that should not remain public.

Public reads

curl 'https://update.estudium.eu/pivo-api.php?q=research&offset=0'
curl 'https://update.estudium.eu/pivo-api.php?id=PIVO-0-0000-0001'

Lists return records, total, offset, limit (50). The next page uses offset=50.

Detail returns record and revision dates. sequence is the decimal ordinal,

issuer_core identifies the issuer, revision is the current revision number.

Keys and creation

An organization creates a key in Manage PIVO → API keys. Its secret appears only

once; only a hash is stored. Keys expire after 90 days and may be revoked immediately.

An account may have 10 active keys, each allowing 120 successful writes per hour.

Keys grant PIVO operations for their issuer only, not account/project management.

Blocked/deleted accounts cannot use their keys. Send the token in Authorization,

never the URL. Use HTTPS and Content-Type: application/json.

curl -X POST 'https://update.estudium.eu/pivo-api.php' \
  -H "Authorization: Bearer $PIVO_TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: journal-2026-article-001' \
  --data '{"action":"create","metadata":{"title":"Example research output","authors":"Jane Doe; John Smith","publication_date":"2026-09","keywords":["education"],"type":"article","publisher":"Example School","url":"https://example.org/article","language":"en","license":"CC BY 4.0","abstract":"An example record."}}'

Success: HTTP 201, {"ok":true,"created":true,"record":{...}}. Reusing an

Idempotency-Key with identical metadata returns the original ID (200); different

metadata conflicts (409). Keys accept 1–100 letters, numbers, dot, colon, hyphen

or underscore. The JSON field idempotency_key is an alternative to the header.

Updating and withdrawal

POST to the same URL with the Bearer token. Read current revision first. Updates

supply complete metadata, not a partial patch.

{"action":"update","id":"PIVO-0-0000-0001","revision":1,"metadata":{"title":"Updated title","authors":"Jane Doe","abstract":"Updated complete abstract.","publication_date":"2026-09","keywords":["education"],"url":"https://example.org/new-location"}}
{"action":"withdraw","id":"PIVO-0-0000-0001","revision":2,"reason":"Duplicate publication"}

Stale revisions return 409, preventing lost updates. Other issuers' records cannot

be changed. The landing page shows revision history; JSON exposes revision numbers

and dates. A withdrawn record cannot be edited or republished.

PDF and API

The API accepts a target URL or metadata.file_id of the issuer's completed PDF.

Upload PDFs through the signed-in web form; Bearer keys do not grant file uploads.

For server-only integrations, use the publication URL on your own server.

Errors and operation

JSON responses include ok, and error on failure. Status codes: 401 invalid/expired

key, 403 wrong owner/account type, 404 not found, 409 idempotency/revision conflict,

422 invalid metadata, 429 rate limit, 503 unavailable storage. Reads use GET, writes

POST, other methods return 405. OpenAPI specification.

MySQL stores the registry, memberships, PDF metadata and key hashes. PDF blobs live

outside the web root in private/update-data/publications. Full internal backups

include logical SQL state, identifier sequences and PDFs. Restore the newest snapshot;

never overwrite newly issued identifiers with an older registry snapshot. Preserve

resolver addresses or permanent redirects when migrating. Back up before deployment.

Why use PIVO and how to start

PIVO provides a stable landing address separate from the PDF location. If the file

moves, update its target URL without changing the identifier cited by readers.

The registry links an output to its CORE issuer and provides metadata, citations

and revision history. It can serve institutional studies and research reports;

an identifier does not itself confer prestige, peer review or database indexing.

Register an organization, complete its card, open Manage PIVO and register an output.

Article authors must provide **title, author names, publication month/year, abstract

and keywords**. PIVO also requires a URL or PDF. Separate authors with semicolons,

preferably Doe, Jane; Smith, John; write institutional authors as {Example School}.

Omit academic degree suffixes from author names. The API accepts 2026-09 or

09/2026, stores 2026-09, and derives the year. Keywords may be an array or

semicolon-separated text, up to 30 entries. Legacy records remain available; missing

required metadata must be completed when editing them.

Search, citations and duplicates

/articles.php combines public personal/organization publications and PIVO records.

Search title, abstract, keywords, author/CAR/ORCID or organization/CORE/ROR. Every

article offers APA 7, IEEE and ISO 690 citations, BibTeX and RIS downloads and link

copying. Add journal, volume, issue and pages for more complete citations. Generated

citations depend on supplied author names and metadata; check the target journal's

requirements. Bibliographic managers can import BibTeX/RIS.

Matching DOI, PIVO reference, PDF checksum or exact title/authors/month without DOI

is grouped into one search item, preferring a PIVO record. Original publications

are not deleted; alias URLs resolve to the canonical item. Different DOI records

are not grouped solely by similar titles. Creating another PIVO for a recognized

output returns 409 with its existing identifier. Idempotency-Key handles retries.

The nine most viewed articles are ranked within the selected calendar month,

defaulting to the current month in Europe/Prague. A month picker shows earlier

periods. Lifetime totals remain separate. Repeated views by the same visitor in

one hour within that month count once; recognizable crawlers are excluded. This

measures detail-page visits, not citation impact or quality. With no visits the

ranking is empty; with fewer viewed articles it contains fewer than nine entries.

Google Scholar and other platforms

Article pages show public abstracts and Highwire citation metadata, with separate

author tags and a full-text link when PDF is available. This prepares the pages

for Scholar crawlers; inclusion is not guaranteed. Use searchable-text PDFs with

a title, authors and references. Scholar's documented file limit is 5 MB, although

eUpdate accepts 20 MiB. See Google Scholar guidelines.

The Google Scholar link searches for the article title; it is not a submission.

Zotero can read embedded metadata; other managers can import BibTeX/RIS.

See Zotero metadata support.

Share the persistent URL on institutional sites, author profiles or other platforms.

eUpdate does not log in to ORCID or submit records to Crossref, DataCite, Scopus or

Web of Science without a separate integration.

Complete API example

{
  "action": "create",
  "idempotency_key": "study-2026-09-001",
  "metadata": {
    "title": "Example educational research",
    "authors": "Doe, Jane; Smith, John",
    "publication_date": "2026-09",
    "abstract": "A complete author-written abstract of this study.",
    "keywords": ["education", "learning analytics"],
    "type": "article",
    "journal": "Example Journal",
    "volume": "2",
    "issue": "1",
    "pages": "10-19",
    "url": "https://example.org/research",
    "language": "en"
  }
}

Read the combined catalogue and citations:

curl 'https://update.estudium.eu/article-api.php?q=education&month=2026-09'
curl 'https://update.estudium.eu/article-api.php?author=CAR-0000-0001'
curl 'https://update.estudium.eu/article-api.php?organization=CORE-00001'
curl 'https://update.estudium.eu/article-api.php?id=PIVO-0-0000-0001'
curl 'https://update.estudium.eu/citation.php?id=PIVO-0-0000-0001&format=bibtex'

Lists return records, total, offset, limit, month, timezone and top. Items contain

lifetime views, selected month_views and a monthly_views map. Detail returns

article and citations. Citation formats: apa, ieee, iso690, bibtex, ris. Private

articles and unattached PDFs return 404 publicly. Publicly linked PDF can be indexed;

private files remain protected by access checks.

Publication and project RSS in Czech and English

The public Czech RSS and English RSS each contain

up to 130 items: 100 recently updated public publications, articles and PIVO

records, plus 30 recent public, non-archived projects. Each project appears

once, using the version with the latest release date. Missing release dates

fall back to the version upload time; projects without releases use their

creation date. Modules do not appear as separate items. All entries are

merged and ordered newest first.

  • Czech: https://update.estudium.eu/feed.xml
  • English: https://update.estudium.eu/feed.en.xml

Channel titles, descriptions, categories and language tags are localized.

Both variants contain the same records; submitted titles, abstracts and author

text are not automatically translated. The storage tab shows a timestamp,

preview and link for each feed. Regenerate RSS refreshes both variants.

Both feeds refresh after publication, PIVO, public profile, project, release,

visibility, archive or owner-login changes. The first request after upgrading

regenerates RSS automatically; unchanged requests do not keep rewriting it.

Publication duplicates are grouped as in the catalogue. Private publications,

withdrawn PIVO records and private or archived projects are excluded. Items

include title, description, author, category, canonical link and a public PDF

enclosure where available. pubDate is the ordering date; dc:date retains the

entered publication date. The canonical URL is the GUID. Reading RSS does

not increase article views.

Readers may retain items after they are removed from the current feed.

RSS does not itself guarantee Google Scholar inclusion.

<!-- Author: PB <pavel.bartos.pb@gmail.com> -->

Profile cards, short URLs and sign-in

Login, full name and organization logo

When registering a person, enter a Login / nickname for signing in

(for example pavel852) and a separate Full name (display name) for the

profile card. Edit the name under My account → My profile card;

admins can also use Users → Edit. It is required and supports up to

100 Unicode characters. Organizations use Organization name in the same field.

The name appears on the profile, vCard, in search results and SEO. Profile

publication still requires user consent. Changing the name does not change

the login, password or CAR/CORE. Existing accounts keep their stored names.

If an account currently has only its login stored as the display name, the

user can fill in the actual name manually. Names are not inferred from CVs or email.

Organization logos use a rounded frame matching their proportions: a square

for square logos and a wider rectangle for landscape logos. Width is limited

by the available space. Logos remain entirely visible without distortion or

cropping on public profiles, in the community and in My account previews.

A person has a public profile URL such as

https://update.estudium.eu/CAR-0000-0002; an organization uses, for example,

https://update.estudium.eu/CORE-00001. These IDs are examples: use the identifier

assigned to the actual account. Changing the display name does not change the

identifier or profile URL. Profiles require an active account and publication consent.

An article or book with PIVO uses https://update.estudium.eu/PIVO-0-0000-0001.

A publication without PIVO uses its existing 32-character publication ID directly

after the domain. Copy its Open link from the catalog or profile. A short URL

does not issue PIVO; only organizations can issue it. Legacy

/profile.php?id=…, /pivo.php?id=… and /article.php?id=… links redirect with

HTTP 301. Canonical URLs, sitemap.xml and the publication feed.xml use the new

addresses. Software keeps /login/project, for example /admin/eweb-server.

To sign in, enter your login, CAR or CORE and the account's normal password.

CAR/CORE matching is case-insensitive. These public identifiers do not replace a

password; blocked accounts cannot sign in. New passwords require at least 10 characters.

Under My account → My public profile, drop a photo or logo onto the upload

area, or choose a file with the file picker. Use one PNG, JPEG or WebP up to

512 KiB and 4000 × 4000 pixels. A preview appears immediately; click

Save profile to commit it. Removing the image also requires saving. File

errors appear beside the upload area, and the server validates the actual image.

The public card has a compact header, contacts and identifiers, education or

business category, affiliations and a filled-in CV. Optional contacts such as

email and phone appear only when their publication boxes are checked.

Organization logos are displayed without cropping. Empty CV sections are omitted.

Author projects / Organization projects combines public software, books,

articles and other publications associated with the account. Use the category

buttons to filter. All cards are present in the initial HTML for search and

indexing. Choose the publication type when adding it to your account or PIVO.

The catalog merges recognized duplicate works. A matching author name alone does

not attach another account's publication to your profile: add it to your own

publications, optionally referencing an existing PIVO. Private and archived

software projects are excluded from the public portfolio.

<!-- Author: PB <pavel.bartos.pb@gmail.com> -->

Deleting check-ins as an administrator

The Check-in / servers page starts with a table showing hostname, program

and version, check-in date, installation ID and approval status. Click a row to expand the

server details and actions; click again to collapse them. The hostname button

also supports keyboard activation.

Under Check-in / servers → Delete check-in, admins can remove all retained

reports for a selected server (up to three). The button in a project's

Check-in tab removes only reports belonging to that project. Reports for

other servers and projects are retained.

Type the server ID in check shown above the confirmation field. If a newer

report arrives, deletion stops: refresh the list and confirm again. Errors

appear inside the dialog. Registered users cannot delete reports, even for

servers assigned to them; the server-side API enforces this restriction.

This deletes received report history. It retains server approval, the pinned

API key and licenses. The server reappears after its next check-in. To revoke

licensed access, change approval or licenses. Internal communication logs are

retained. Successful deletion appears as checkin.delete in the audit history,

with the administrator, timestamp and server ID.

Overview and complete details (1.7.1)

Check-in / servers lists the most recently reported servers first. Expand a row

and open Server details. eWeb reports hosting, modules, services, monitoring

and security; eCast reports channels, clients, recordings, disks and packages.

Sections include all received fields, including new or unknown fields. Missing

values are not invented and sensitive credentials are masked.

The authenticated interface uses GET /api.php?action=server.report&server=ID.

Optional project=PROJECT_ID restricts the detail to matching project reports.

It requires a login, server permissions and, when scoped, project permissions.

Machine clients continue to send reports to /check/; its URL is unchanged.

<!-- Author: PB <pavel.bartos.pb@gmail.com> -->

Uploading multiple ZIPs

Under Upload package, drop several ZIPs into the upload area or select them

together. The empty catalog drop area also supports this. One ZIP keeps the

existing full review form and manual publish button. Overwriting an existing

version also requires approval in a separate dialog.

Two or more ZIPs start a sequential queue, up to 20 files. Each ZIP is uploaded

in chunks, extracted and inspected for install.json and README. Existing limits

still apply: 20 uploads per hour, 512 MiB per ZIP, up to 2 GiB extracted per package.

package.parent_software_id and package.module_id. A complete newer version

is added automatically. Versions are compared by version value, not file order.

project may supply a known name, description or README. Version, release date,

supported systems and installation commands are not guessed from an older release.

access settings yourself. Uploading another version does not change an existing

project's or module's permissions, visibility or Open/paid access.

is inspected, a single summary lists every affected program/module. Confirm

once to apply the listed replacements sequentially. Cancel, Escape or stopping

the queue preserves existing releases. New releases already published remain.

files absent from the new ZIP. The release ID and link remain unchanged without

creating a duplicate. Licenses and release statistics are retained. The release

date comes from the new metadata. If another publisher changed the release

since approval, the file fails and needs a fresh review. Several ZIPs targeting

the same project/module version in one queue are rejected.

an in-flight request may complete and already published versions are retained.

Navigating away also stops processing. This is not a server background job and

the queue does not resume automatically after closing the browser.

individually. Unpublished temporary ZIPs are reclaimed on a later upload after

24 hours. The final summary links to successfully updated projects.

Installation commands from manifests never execute on the eUpdate server during upload.

eUpdate 1.7.6 — RSS, introduction and project overview

Author: PB <pavel.bartos.pb@gmail.com>

Release date: 2026-09-11

up to 100 publications/articles/PIVO records plus 30 public projects.

its most recently dated release. Missing release dates fall back to upload

time; projects without releases use their creation date.

text and categories are localized; submitted titles and descriptions retain

their original language. Both channels contain the same records and links.

Regenerate RSS refreshes both. Diagnostics and RSS discovery metadata include

the English channel. Project, release, visibility and owner-login changes

refresh both feeds automatically, as does the first request after upgrading.

columns and a single column on smaller screens. Hover highlights the rendered

text line and the exact word. Text remains selectable and readable without JS.

data reuse the introduction and its three topics.

closed expandable section with downloads, source files and management actions.

Server-rendered HTML uses the same grouping.

and show project page views separately. Switch between the last 12 months

and the last 30 days. The latest version is explicitly identified by number.

selected-period and lifetime downloads. Tables remain available if charts

cannot load. Module downloads are excluded from this project-version total.

is counted at most once per session every 30 minutes, excluding project

managers' own visits. These are recorded events, not unique-person counts.

The current day and month are incomplete.

RSS details: /docs/registry.en.md. No new cron or SQL schema change. The SQL

restore guard from 1.7.5 and all 1.7.4 fixes remain included. Data comes from

the originally supplied 1.7.3 snapshot; later live changes are not included.

eUpdate 1.7.5 — SQL restore concurrency fix

Author: PB <pavel.bartos.pb@gmail.com>

Release date: 2026-09-11

The original dump correctly drops each table before creating it. Older eUpdate

versions nevertheless run CREATE TABLE IF NOT EXISTS on every request and

monitoring cron call. A request in the DROP/CREATE interval can recreate the

table and cause ERROR 1050. The subsequent zstd Broken pipe is a consequence

of the failed SQL import.

The distributed SQL now takes the existing mysql_db advisory lock before its

first table change, using eupdate: plus DATABASE(). This also coordinates older

eUpdate versions and supports an eWeb restore into a renamed database. Lock

acquisition waits at most 60 seconds and fails before the first DROP if the

lock is unavailable. Completion releases the lock; a disconnected import

session releases it automatically. Original SQL statements, schemas and row

values remain unchanged.

Normal HTTP requests and cron calls no longer create missing tables or seed a

default administrator in incomplete databases. They return a clear 503 response.

Explicit private/update-tools/bin/migrate-mysql.php execution can still initialize

an empty application database. It does not overwrite an incomplete schema.

After an interrupted import, repeat eWeb restore from this archive with Files

and Database selected. It contains the supplied 1.7.3 snapshot and all 1.7.4/1.7.5

application changes; later live data changes are not included. Keep the existing

private/update-tools/collect-monitor.php cron running every minute; no additional

cron job is required.

Verified with 15 focused checks on an isolated MariaDB, including reproduction,

concurrent requests from both application versions, repeated import, row equality,

lock failure and automatic release. No live cluster deployment was performed.

Future external dumps need the same guard for coordination; the included

private/update-tools/bin/wrap-restore-sql.py adds it to an uncompressed SQL dump.

eUpdate 1.7.4 — storage, XML, monitoring and diagnostics

Author: PB <pavel.bartos.pb@gmail.com>

Released: 2026-09-11

Storage provides a separate full backup button, including when no migration

is pending. Migration appears only for pending releases. Available backups are

listed with time, owner, scope, size and download; retention stays at two per

account. SQL rollback preserves original folders and removes new copies. An existing

destination is reused only if every file hash and the directory structure match;

different or extra files stop migration.

Sitemap and publication RSS show file modification time (including seconds),

size, item count, the first 50 items and escaped XML source. Both files can be

regenerated. File modification and individual content update times are distinct.

RSS includes up to 100 public publications, articles and PIVO records, excluding

software and modules.

If restricted PHP has no current host metrics, settings invokes a fixed,

read-only Python helper under the same OS user. It requires /usr/bin/python3 and

proc_open. It does not change hosting permissions or the cluster cron scheduler.

Two initial samples provide CPU and network averages; subsequent requests reuse

fresh samples in existing MySQL settings, always scoped to the local hostname.

Settings → Download diagnostics creates an administrator-only ZIP containing

PHP environment, metrics, storage/XML status, database row counts, the last

200 audit/checker events, available cron configuration and log tails. It includes

up to 20 files, 128 KiB each and 2 MiB total; compressed rotations and symlinks

are skipped. Missing inputs and helper failures are reported in collection.json.

Creation requires POST and CSRF. Downloads require an administrator session,

expire after 30 minutes, and at most five packages remain between exports.

Recognized secrets, credential lines and URL queries are redacted. Inspect the

archive before sharing: domain/account names, IP addresses and custom error

messages may remain. Diagnostics are not a restore backup. Unavailable metrics

remain explicit if all permitted collection methods fail.

Distribution uses eweb-backup-v3. It preserves the original 1.7.3 SQL snapshot,

project files, check-ins, licenses, identities and hosting configuration. The

MySQL schema is unchanged. Changes made later on the live host are not included.

eWeb cron

For update.estudium.eu, enable the eUpdate monitoring job with script

private/update-tools/collect-monitor.php and expression * * * * * (every minute).

The supplied backup already includes this job in cron/cron.json; do not create

a duplicate if it is listed in eWeb. Cron collects metrics in the background;

the settings page can also collect samples while it is open.

<!-- Author: PB <pavel.bartos.pb@gmail.com> -->

eWeb monitoring fix since 1.7.3

eWeb limits PHP-FPM to web/, private/ and temporary directories. The previous

scan started at their inaccessible parent and incorrectly treated it as empty.

The fix scans private/ and web/ directly. Project data · private/ includes

private files and legacy layouts, excluding separately counted logs and backups.

The Total private/ figure includes those private logs/backups as well; it is

an additional subtotal and is not added to the chart again.

Disk cards describe the whole volume; the chart describes measured application

data. Directory sizes refresh every minute or on demand. Inaccessible directories

produce an explicit partial measurement rather than a valid zero. Symbolic links

are skipped and the scan retains its time limit.

PHP restrictions also block /proc. The backup includes

private/update-tools/collect-monitor.php and an eUpdate monitoring job in

cron/cron.json, scheduled * * * * *. eWeb 0.8.9 calls its native

eweb-cron sync-domain during file restoration. The job runs as the domain

account, not root. PHP-FPM restrictions and system credentials are unchanged.

Each minute the collector takes six samples ten seconds apart, running for

about 50 seconds. Existing MySQL settings hold at most eight recent samples

per hostname, up to 16 hosts. No new SQL table or JSON database is introduced.

PHP reads only its own host's samples. Values older than 90 seconds are not

presented as current. Directly available metrics take priority. Missing network

interfaces are not fabricated. Domain log file sizes can come from the same

collector with a maximum age of 150 seconds, without counting SQL logs twice.

Allow up to a minute for the first cron run. If no sample arrives, check the job

and its cron log in eWeb. For a short test as the domain account:

php /var/www/update.estudium.eu/private/update-tools/collect-monitor.php --once

Native eWeb domain cron follows cluster controller selection. If a different

member serves the website, its administrator must arrange local collection under

the domain account. Another member's metrics are never substituted. The UI shows

the source hostname and whether it is waiting for the collector.

<!-- Autor programu: PB <pavel.bartos.pb@gmail.com> -->

See the current [eWeb monitoring fix](#monitoring-173) for 1.7.3.

<!-- Author: PB <pavel.bartos.pb@gmail.com> -->

Releases, modules, logs and sign-ins since 1.7.2

Module overview and licenses

The project Modules tab includes a compact table above the cards, sorted

alphabetically by name. It shows a linked module name, the latest version and

that release's date. Versions are compared by number, not upload time. A dash

means no release date is available. Project permissions and module visibility

still apply. The license table also displays the latest available version.

A license covers the module and its future updates until expiration; it is not

restricted to the displayed version. Only the server's program is offered.

Overwriting and deletion

One ZIP keeps its full review form. Publishing a version already stored for the

same program/module requires explicit overwrite approval. Multiple ZIPs use

one summary and one approval for all replacements. The ZIP and extracted files

are replaced while the release ID and link remain unchanged. There is no duplicate

version. A concurrent change to the original release invalidates stale approval.

Deleting a release, module or project removes its version files and Git cache.

The existing automatic backup before deletion remains, with two private backups

retained per creating account. A backup is not an active project release.

If disk permissions prevent cleanup after the SQL change commits, the API

returns cleanup_warning and records the failure in the PHP log. An administrator

must check the private staging/retired-* directories.

Git clone

/git/software-id.git also works through the Nginx index.php fallback included

in the supplied backup. The host needs Git and PHP proc_open enabled. Copy the

actual clone command from the project:

git clone https://update.estudium.eu/git/software-id.git

Private projects still require X-Project-Secret. Overwriting a release changes

its tag and may rebuild subsequent Git history. In existing clones, use

git fetch --force --tags origin and review the changes; a regular pull may

reject divergent history. A fresh clone provides the current published state.

Local edits are not deleted automatically. Git push remains disabled.

Forwarding logs to eWeb

for example https://eweb.example.org:8443, and the sender hostname.

fingerprint shown in eUpdate. Test delivery again.

as the domain account with access to the same MySQL configuration as PHP.

The integration uses /api/log-ingest.php operations offer, status, events,

tested against eWeb 0.8.9. Its log analyzer must be enabled. TLS certificate and

hostname verification are required; redirects are not followed. A random sender

ID and secret token live in private MySQL settings. The token is never displayed

in the form or logs and is unrelated to the eWeb administrator password.

Forwarding includes new audit events (including sign-ins), checker results and

basic diagnostics for unhandled application errors. Passwords, keys and full raw

check-in reports are not sent. System/Nginx logs are not read, and historical audit

events are not backfilled. Forwarding defaults to disabled.

The private MySQL queue holds up to 2,000 events. Overflow drops the oldest and

tracks the count. A batch has at most 100 events and under 240 kB; regular retries

wait at least a minute. Events leave the queue only after full acknowledgement.

Outages, pending approval and paused receivers retain the queue. Stable event IDs

allow eWeb to deduplicate retries. Changing destination or hostname clears the

pending queue and does not rename an already approved receiver identity. Disabling

forwarding pauses delivery.

Failed sign-in ban

The fifth failed sign-in in a rolling 60-second window bans that login for

24 hours from the fifth attempt. The account's login and CAR/CORE share the ban;

changing letter case or IP cannot bypass it. Correct passwords are also rejected

during the ban. Further attempts do not extend it. It expires automatically.

A successful sign-in before reaching the threshold resets the counter. Existing

sessions remain signed in. The API returns HTTP 429 and remaining seconds in

Retry-After and retry_after. The existing IP attempt limit also remains.

MySQL table structures do not change in 1.7.2. Log settings and bans use the

existing settings and rate stores. Incoming check-ins remain JSON files.

Server status, disk, CPU, RAM and network

eUpdate settings shows administrators the volume's total, used and

available space in percentages and MiB/GiB. CPU utilization averages actual

busy CPU time between samples; system load averages for 1, 5 and 15 minutes are

shown separately. RAM shows used/available memory and average utilization.

Network / LAN uses the default-route interface; details list other interfaces.

RX/TX mean receive/send. Rates use B/s, KiB/s, MiB/s, etc. Transfer counters

apply since each interface started; virtual and physical totals are not added.

Samples refresh every 10 seconds while settings is open. CPU/network rates need

two samples; averages cover up to the last minute. Sampling stops on navigation,

and only a short history from the CLI collector is retained in MySQL. These are metrics visible to PHP: on

shared hosting they can describe the whole host. Access depends on /proc

permissions. Missing metrics are marked unavailable rather than shown as zero.

The doughnut chart and table describe measured eUpdate data, not the whole

disk: database, project data (ZIPs, sources and modules), logs, backups and other

files. Each category shows a size and percentage. Database size estimates table

and index allocation. Audit/checker log payloads and the pending delivery queue

are subtracted from database size and counted with logs, avoiding double counting.

Files use content lengths rather than allocated blocks. The database may be on

another server. The volume may also store unrelated applications, so chart totals

need not match the volume's total used space.

Directory sizes are scanned on opening settings or choosing **Refresh including

data sizes**. Normal ten-second samples do not walk directories. The scan skips

symbolic links and stops after four seconds or 300,000 files. Partial results

are explicitly marked.

Clear all logs

An administrator chooses Clear all logs and types CLEAR LOGS to confirm.

This clears audit events, checker communication logs, the pending delivery queue,

regular files below logs/ and private/update-data/logs/, plus legacy

checker-log*.json files directly inside the data directory. Open file contents

are truncated so services can continue writing. Symbolic links are skipped;

locked or non-writable files are reported in the result.

Installation check-ins, licenses, uploaded packages (including their .log

source files), sender identity and sign-in bans are preserved. Logs previously

sent to another eWeb must be managed there. Retained backups are not rewritten.

MySQL can retain allocated space for reuse after row deletion; this button does

not run OPTIMIZE TABLE. New activity creates new logs. Administrative settings

retain the time and account of the last cleanup.

License assignment in eUpdate 1.7.2

Author: PB, pavel.bartos.pb@gmail.com

In Check-in / servers, expand a server and choose Grant / change license.

The table lists available paid modules, their projects, assignment checkboxes,

expiration dates and status. An administrator must approve the server first.

Admins manage all licenses; registered accounts need project/module permissions

and the server assigned to their account. Open modules do not need assignment.

A partial selection has an indeterminate state. Expiration dates are preserved.

The specified day is included in full in UTC. Past dates remain visible and

the license is marked as expired.

all or closing the dialog does not save changes on its own.

fields inside the dialog. If another administrator changed the same license,

close the dialog, refresh the server list and reopen licenses for current values.

Assignments do not change server keys, hostnames, allowed IPs or approval.

Clients continue to use the existing /check/ authentication and licensed downloads.

MySQL table structure is unchanged from 1.6.8.

Linking licenses to the reported program

Both the catalog and save endpoints use the program in the latest received

check-in. software_id must match the published program ID, for example

eweb-server or ecast-pipe-server. Legacy reports without software_id use

an exact program-name match. Unknown software is not offered unrelated modules.

The same validation applies to license.save and licenses.save.

Rows are compact. Long tables scroll independently with a sticky heading.

Selecting all does not change expiration dates.

Module versions

The Latest version column shows the highest available module version.

The license covers the module, including future updates until expiration.

It is not restricted to the displayed version.

eStudium.eu

Package and update documentation

Public documentation · no login required. Program author: PB, pavel.bartos.pb@gmail.com.

eUpdate 1.7.9

Hosted applications and eLoader packages now declare runtime requirements and licenses. Copy an installation link or find the latest compatible version.

Installation API and package format

1. ZIP layout

Each program release and each module has a separate ZIP. Recommended root entries:

ZIP pathPurpose
install.jsonUTF-8 metadata using valid JSON without comments.
readme.mdDescription, requirements, installation and upgrade instructions.
install.shLinux installer when declaring an automatic Linux command.
install.ps1Windows installer if actually supported.
src/…Program source and data; layout is chosen by the publisher.

A wrapper directory such as example-app/install.json is supported. The manifest closest to the root takes priority. A relative README path is resolved against its directory first. Without an explicit working directory, the manifest directory is used. archive_metadata.working_directory is relative to the extracted ZIP root.

Limits: ZIP 512 MiB, extracted total 2 GiB, individual file 512 MiB, 30,000 entries. Encrypted archives, symlinks, absolute paths, ../, duplicate paths and special files are rejected. A normal ./ prefix is supported. Uploads use small chunks; leave the page open during transfer.

A missing or invalid manifest does not block import. Complete required fields manually and review before publication. Metadata corrections do not modify the original ZIP or its SHA-256.

Open Files on a release to see each file type (php/html/js/…). Select a file and use Download file even for binary files or files above the 512 KiB preview limit. PHP/HTML downloads are attachments and never execute on the update server. Only the authenticated owner/admin can download individual paid files; licensed clients download the full ZIP.

2. install.json

This is a format example, not verified compatibility information for an actual program. Declare only systems and commands you have tested.

Download example JSON

{
  "software": "Example App",
  "software_id": "example-app",
  "version": "1.2.0",
  "release_date": "2026-09-07",
  "author": { "name": "PB", "email": "pavel.bartos.pb@gmail.com" },
  "description": { "cs": "Ukázkový program pro dokumentaci.", "en": "Example program for documentation." },
  "package": { "type": "release" },
  "compatibility": {
    "os_types": ["linux", "windows"],
    "distributions": [{ "id": "ubuntu", "name": "Ubuntu", "versions": ["24.04"] }],
    "os_versions": ["Windows 11"]
  },
  "installation": {
    "commands": {
      "linux": { "supported": true, "command": "bash ./install.sh" },
      "windows": { "supported": true, "command": "& ./install.ps1" }
    }
  },
  "documentation": { "readme": "readme.md" },
  "archive_metadata": { "working_directory": "." }
}
FieldMeaning and rules
softwareProgram or module name, up to 100 characters.
software_idStable program ID: 2–80 characters, a–z, digits and hyphens. Clients use it for updates.
versionVersion, up to 64 characters. Recommended: 1.2.3. Letters, digits, dots, hyphens, underscores and plus signs are allowed. Published versions cannot be overwritten.
release_dateRequired author release date, YYYY-MM-DD. Import also recognizes released_at, release.date and release.released_at, including the date at the start of an ISO timestamp. Complete missing dates manually. Upload time is recorded separately.
description.cs / enShort description. The form imports Czech or falls back to English. User content is not automatically translated.
authorOptional author and contact, preserved in metadata. Never include secrets.
compatibility.os_typesRequired list: linux, windows, macos, other, source.
compatibility.distributionsFor Linux, provide distribution IDs, names and versions; alternatively explicitly set any_linux_distribution: true.
installation.commands.OSFor each selected OS, use supported: true and a nonempty command, or supported: false, mode: "manual" with README instructions. Automatic helper scripts are generated for Linux and Windows.
documentation.readmeREADME path. Otherwise the server looks for readme.md. Instructions are required before publishing. Imported README and manifest are limited to 256 KiB each.
archive_metadata.working_directoryCommand working directory, e.g. . or example-app; must exist in the ZIP. Adjust the dot in the example if using a wrapper directory.

Unknown metadata fields are preserved and editable. Confirmed form values take priority for name, version, description, OS, commands, working directory, README and date. Old releases without dates show “Not provided”; the owner can add a date.

3. Separate Open and paid modules

Create the parent program first. Upload a separate module ZIP using “Program module”. Each module has its own stable ID, description, versions and release dates. Add this object to the manifest:

{
    "type": "module",
    "parent_software_id": "example-app",
    "module_id": "monitoring",
    "access": "open",
    "description": "Monitoring module example."
}

Download module example

parent_software_id identifies the program; module_id is unique within it. Keep both unchanged across versions. The manifest prefills type, an accessible parent project, ID and access. Existing modules retain their stored access setting when a new ZIP is uploaded.

AccessPublic informationDownloads and updates
openDescription, versions, metadata, ZIP and sources.Free without login or license approval. “Open” is an access setting, not a source code license; document actual legal terms in README/LICENSE.
paidPublic description, version, release date and basic technical information.Authenticated owner/admin, or an approved server with matching ID, key, hostname, IP and an active module license.

Payments and invoicing are not automated. An authorized manager grants licenses after terms are agreed. Existing private modules default to paid access. Access changes apply to every release; downloaded copies cannot be revoked.

4. Public update feed

/updates.json is a public JSON snapshot refreshed when projects, modules, releases or release dates change. It lists active programs and the highest available version of each program/module. Archived projects are not offered for updates.

/updates.php reads the current data store directly. It can compare a program version using /updates.php?software_id=example-app&version=1.1.0; update_available is true only for a higher available version.

Find programs by software_id, and modules by parent program ID plus modules[].software_id. Compare versions using PHP version_compare, not string sorting: 1.10.0 is newer than 1.9.0. Do not use release dates for version comparison.

curl --fail --silent --show-error -H 'Cache-Control: no-cache' \
  'https://update.estudium.eu/updates.php?software_id=example-app&version=1.1.0'

latest contains version, release_date (author date; possibly null for old data), published_at (publication time in eUpdate), release_id, sha256, bytes, compatibility, requires_license and download_url. Programs without a public release have latest: null.

Open modules have requires_license: false and a public download URL. Paid modules have requires_license: true and download_url: null. An authorized server obtains licensed links from authenticated POST /check/. No keys, users or granted licenses are exposed in the public feed.

For a paid download, send X-Server-ID, X-Server-Hostname and the pinned 64-hex key in X-Eweb-Api-Key or Authorization: Bearer …. Verify the downloaded ZIP hash, supported OS and publisher instructions before execution. Never put secret keys in URLs.

This documents the server interface. The installed eWeb client must implement feed retrieval, version comparison and the update prompt. Publishing this JSON does not modify existing eWeb client code.

5. Check-in manual for eclone-server

Project ID: eclone-server. Each installation sends periodic HTTPS POST requests to https://update.estudium.eu/check/. Machine requests use an API key, not admin/admin or browser CSRF tokens. Administrative GET access to /check/ remains admin-only.

First registration

  1. Create a stable installation ID once (e.g. UUID) and a secret API key containing 32 cryptographically random bytes encoded as 64 hexadecimal characters.
  2. Keep the identity and key in private configuration. Reuse them across reports. Generate a new checkin_id for each new report. A cloned installation on another server needs its own identity.
  3. Send the key in X-Checkin-Api-Key. X-Eweb-Api-Key, X-Ecast-Api-Key, X-Server-Checkin-Key and Authorization: Bearer are also supported. Never place the key in a URL or JSON payload.
  4. The first valid key is pinned to the ID (TOFU). Registration is not server approval or a paid license. If the key is lost, an admin must verify the installation and reset its pinned key. Do not generate replacement keys repeatedly for the same ID.

Report JSON

{
    "schema": "eupdate-checkin-v1",
    "server_id": "00000000-0000-4000-8000-000000000001",
    "checkin_id": "0123456789abcdef0123456789abcdef",
    "software": "eclone-server",
    "software_id": "eclone-server",
    "version": "1.3.0",
    "installation": {
        "id": "00000000-0000-4000-8000-000000000001",
        "installed_at": "2026-09-01"
    },
    "system": {
        "hostname": "node.example.org"
    }
}
FieldRule
software_idExact stable ID of the published program; links reports to its project Check-in tab.
server_id / installation.idStable identity of this installation. eWeb also supports eweb_id; eCast supports ecast_id. Do not send conflicting IDs.
checkin_idFresh 32-hex ID for each new report. Reuse it when retrying the same report after a network failure. Required by eweb-checkin-v2.
software, versionProgram name and actually installed version, not the latest offered version.
installation.installed_atOptional actual installation date or ISO 8601 timestamp. Omit when unknown. It is neither first report time nor software release date.
system.hostnameActual server hostname. Paid module access checks it against the approved hostname and source IP.

A hosting application may add webhosting.domains_count and webhosting.domains, an array of objects with domain, enabled, php_version and ssl.status. OS, hardware, software_stack and services can provide further details. Never send passwords, private keys or database credentials.

Example sender

Download Python 3 example client

The example uses only the Python 3 standard library on Linux and Windows. It preserves identity in a private directory. Linux directory/file permissions are 700/600; restrict Windows ACLs to the service account. Default identity path: ~/.local/state/eupdate-checkin/eclone-server/identity.json. Never include this file in a public ZIP.

python3 send-checkin.py --software-id eclone-server --version 1.3.0 --hostname node.example.org --installed-at 2026-09-01

On Windows use py -3 instead of python3. Replace the version, hostname and date with actual values; omit an unknown date. Use a separate --state-dir for each installation of the same program on one machine. Repeated execution as the same account preserves the key and ID. The script does not install updates or invent installation acknowledgments.

Responses, retries and licenses

HTTP 200 and ok: true mean the checker processed the report, not that an update was installed. Responses include request_id, server_id, authentication, duplicate, license_status, updates and modules. updates[].update_available compares the installed program version. Select modules by parent_software_id and module software_id and compare module versions. Open modules may be offered before server approval.

Paid modules require an admin-approved hostname, actual source IP (public outbound IP behind NAT) and server owner. The project owner/admin then grants the module license. Knowing a hostname or completing first registration does not grant a paid license.

HTTPClient action
400 / 422Correct JSON or required fields; do not retry unchanged.
401 / 403Check key format, pinned identity and permissions. Do not automatically replace the identity.
413Reduce the report size. The app limit is 1 MiB; a proxy may impose a lower limit.
429Slow down. Limit: 120 reports per minute per source IP.
5xx / network failureRetry with delay and random jitter, using the same payload and checkin_id. Avoid tight retry loops.

Daily reports and reports after a version change are sufficient for small deployments. Stagger multiple servers. Only the latest 20 reports per server are retained; this is not a permanent installation audit. The project owner/admin can use the Check-in tab; registered owners see assigned servers only.

To acknowledge a response, a later report may include checker_feedback with response_id from the previous request_id and a status of received, downloaded, installed, failed or ignored. Report installed only after a successful installation. Optional error_code is limited to 80 characters and must contain no secrets.

6. Read package versions and specifications as JSON

Every public program release has a JSON specification button. It opens a public /specifications/RELEASE_ID.json file without a password. The file describes that specific release, not necessarily the latest one.

  1. Open updates.json and find software_id = eclone-server in projects.
  2. latest.version is the highest available version; latest.release_date is its release date. A null latest means no public release exists.
  3. Follow latest.specification_url. For a program it points directly to its full .json specification.
  4. For an older release, use its JSON button in release history or the version-specific API below.

Latest program specification:

https://update.estudium.eu/specification.php?software_id=eclone-server

A specific version, if actually published:

https://update.estudium.eu/specification.php?software_id=eclone-server&version=1.3.0

The PHP endpoint returns application/json just like the .json file, without login. Unknown programs or versions return HTTP 404. Specifications remain public after archiving because archiving does not delete releases. Deleted releases lose their specifications.

FieldMeaning
schemaeupdate-package-specification-v1
software_id, version, release_idStable program ID, version number and package release ID.
release_date / published_atAuthor release date / publication time in eUpdate. Unknown historical dates are null.
install_jsonFull confirmed metadata: description, author, compatibility, dependencies and commands. Includes publisher corrections; it may differ from the original manifest inside the unchanged ZIP.
bytes, sha256, file_count, languagesOriginal ZIP size, verification hash, file count and source language breakdown.
readme, download_urlConfirmed instructions and original ZIP download URL.

Command-line example

curl --fail --silent --show-error   'https://update.estudium.eu/specification.php?software_id=eclone-server&version=1.3.0'

Use curl.exe on Windows, or load the JSON object in PowerShell:

$spec = Invoke-RestMethod 'https://update.estudium.eu/specification.php?software_id=eclone-server'
$spec.version
$spec.release_date
$spec.install_json.compatibility
$spec.install_json.installation.commands

Open modules have a public dynamic specification: /specification.php?software_id=eclone-server&module=MODULE_ID&version=1.0.0. The module parameter accepts an internal ID or stable module_id. Paid modules have only a restricted public update summary, because full metadata may include private installation details. Changing Open access to paid immediately prevents further public specification requests. Previously downloaded copies cannot be revoked.

Accounts, file previews and public project URLs

The login page links to registration. A new account can manage its own projects immediately. Only admins can change user roles in Users → Edit → Role. After a role change, sign in again.

Package files offer Preview and code for Markdown and HTML, and syntax coloring for PHP, C/C++, JS, Python, CSS, JSON and other recognized formats. HTML runs in an isolated static preview: scripts, forms and external resources are disabled. Local stylesheets and raster images can be loaded from the same package (up to 16 assets / 8 MiB, 512 KiB per CSS file and 2 MiB per image). CSS imports and CSS image URLs are not loaded.

Each project has a public URL /LOGIN/SLUG, server-rendered content, description, canonical and sharing metadata. sitemap.xml updates automatically whenever projects, versions or modules change, including archiving, deletion and backup restoration. Only sitemap.xml is generated. Archived projects are omitted and marked noindex; deleted projects return 404.

English example package

Download complete example ZIP

Includes install.json, README, a nested program directory, Linux and Windows entry points, HTML, CSS and C examples. Upload it to try metadata import. The sample scripts only print a message.

Publisher metadata and community

Upload prefills author.name, author.email, author.website and project.website (fallback: homepage). The publisher may edit them before publishing. Manifest author data are separate from the account profile; public ZIPs and specifications expose the author email already contained in the package. Your account email is never copied there automatically.

{
  "homepage": "https://www.estudium.eu",
  "author": {"name": "PB", "email": "pavel.bartos.pb@gmail.com", "website": "https://www.estudium.eu"},
  "project": {"name": "eWeb", "website": "https://www.estudium.eu", "updates_url": "https://update.estudium.eu/project.php?software_id=eweb-server"}
}

Registration requires a private email and consent to publishing profile fields. Edit your nickname, biography, CV, photo and website under My account. Consent can be withdrawn to hide the profile. Community search never searches or displays emails. Collaborators are added by exact login or email and can edit all current and future projects owned by the inviting account. Only that owner manages their collaborators. Messages remain visible only to sender and recipient; unread messages appear after login.

Admins can block, unblock or delete other accounts. Deletion first creates a full backup and transfers projects and servers to an active account. Popularity score is 5 × ZIP downloads + project views; views by project editors are excluded and repeat views count at most once per browser session per 30 minutes. This is an activity indicator, not a count of unique humans.

Visibility and SecretID download links

Set Public or Private when creating a project or module. Change it later in project Settings or the module editor. Private projects (including their modules) are excluded from the public catalog, profiles, sitemap and update JSONs. A private module can also be hidden inside a public project. Admins, owners and their collaborators retain access.

Each project and module has an independent random SecretID. Copy its latest-version ZIP link from Settings. Anyone holding that link can download without login or a machine license, including paid modules. The project key grants only program access; module keys grant only their own module. Rotate a key to invalidate older links. SecretID grants ZIP downloads only, not editing, file previews or JSON specification access.

GET /download.php?project=PROJECT_ID&secret_id=PROJECT_SECRET
GET /download.php?project=PROJECT_ID&module=MODULE_ID&secret_id=MODULE_SECRET

Add &release=RELEASE_ID to pin a version; otherwise the highest version is returned. You can send X-Project-Secret as an HTTP header instead of a query parameter to avoid putting the key in the URL. Existing downloaded copies cannot be revoked. Treat copied links as credentials; standard web access logs may record their URLs. Regular paid-module machine downloads still require their approved server identity and active module license.

Import from GitHub

After signing in, choose Import from GitHub and enter https://github.com/OWNER/REPOSITORY. Optionally supply a branch, tag or commit; leaving it empty selects the default branch. A /tree/BRANCH link is also supported. eUpdate resolves the commit and downloads a source ZIP snapshot. It does not transfer Git history, issues or separate release attachments. Check submodules, Git LFS content and the source license before publishing.

eUpdate loads install.json and README, prefills author and project metadata, and uses repository name, description and website where the manifest lacks them. Missing version, release date, OS support and installation instructions must be filled in the review form. Review the working directory because GitHub adds a wrapper directory. Nothing is published until the publisher confirms the form. Source repository URL, ref and commit remain recorded in metadata.

Only public github.com repositories are supported, without a GitHub token. For a private repository, upload an exported ZIP. The eUpdate host needs outgoing HTTPS to api.github.com and codeload.github.com, trusted CA certificates and PHP HTTPS streams. Limits: 6 imports per IP per hour, ZIP 512 MiB and extraction 2 GiB. GitHub may apply its own rate limits. Large imports can hit the hosting proxy timeout; ZIP upload remains available.

GitHub source archive documentation

Public author cards and vCard

Each active author with profile consent has a public page /profile.php?id=USER_ID, linked from projects and included in sitemap.xml. It contains server-rendered name, bio, CV and public projects, canonical/share tags and ProfilePage/Person structured data. Withdrawing consent, blocking or deleting an account removes the profile from sitemap and makes its page, photo and vCard unavailable.

In My account, fill in phone, personal website, LinkedIn, email and Wikipedia, and select each contact you wish to publish. All contact checkboxes start unchecked, including existing accounts. These choices apply to public HTML, API, structured data and vCard. Bio and CV remain public with profile consent; avoid placing hidden contacts in those texts. The account email is only public if its own checkbox is selected.

/vcard.php?id=USER_ID downloads a vCard 4.0 file with nickname, bio, selected contacts and an embedded profile photo. Contact applications vary in their support for embedded images. URLs and UTF-8 are preserved, lines use CRLF and standard byte folding. Previously downloaded cards and third-party search caches cannot be recalled by unchecking a field.

Google measurement settings

Admin → eUpdate settings offers Off, GA4 (G-…) or Google Tag Manager (GTM-…). Only an ID is stored; pasted scripts are not accepted. Measurement is off by default. The local consent control loads Google only after Allow; Decline loads no remote tag. Measurement settings allows later withdrawal and reloads the page without tracking. Logged-in users, private projects, API, ZIPs and administration do not receive the loader.

In the GA4 web stream, disable Enhanced Measurement, especially history changes, form interaction and outbound clicks. eUpdate sends manual page_view events for public page loads and opened project/profile views, with sanitized page_location, a generic page_title and empty page_referrer. It does not send typed searches, contact values or SecretID. It does not count every hash-only tab as a pageview. Configure a GTM custom event trigger for eupdate_page_view and data layer variables page_location, page_title, page_referrer. Do not enable contact/form collection, additional trackers or history triggers in the container. Container contents remain managed in Google; the site's CSP intentionally does not enable arbitrary external hosts or unsafe-eval.

The backup supplies configuration and consent handling; it does not create a Google account/property/container. Verify the chosen ID in Google Realtime after deployment and consent. Structured data and sitemap improve machine readability but do not guarantee search indexing or ranking.

OS-independent source code

Use compatibility.os_types: ["source"] for source packages such as HTML or portable PHP applications. Select Source code / OS independent in the upload form. No operating system, Linux distribution or automatic installation command is required. A name, software_id, version, release_date, description and README are still required.

Explain PHP/runtime versions, extensions, browser, database, configuration and deployment steps in README. Optional requirements fields are preserved in the manifest. Source is a distribution category, not a guarantee of native support on every operating system. You can combine it with concrete OS values; those OS entries still require their normal installation information.

For source, eUpdate records installation.commands.source = {"supported":false,"mode":"manual","command":null}. No Linux/Windows install helper is generated from the source category. ZIP download, versions, modules, GitHub import and updates/specification JSON continue to work; clients should recognize source as a portable package and show README rather than attempt a native OS installer.

Download source install.json · Download complete source ZIP (EN)

{"compatibility":{"os_types":["source"]},"documentation":{"readme":"README.md"}}

Local backups and retention

Every successful backup is stored privately on the server and remains downloadable in Backups. Only the two newest successful backups per creating account are retained, across project, full-archive and automatic pre-change backups. The third completed backup removes the oldest ZIP and its metadata. Failed creation does not remove existing backups. The limit is applied when that account next creates a backup; it does not delete files downloaded to your computer. Admins can view retained backups of all accounts.

Backup directory layout

Internal backups now use schema estudium-update-backup-v2 and preserve packages/login/project/version and packages/login/project/_modules/module/version. Metadata storage_path matches ZIP paths, including exports from legacy ID directories. Restore 1.4.0 accepts full v1 and v2 backups. Use the current restore tool for new v2 backups. The eWeb domain backup format remains eweb-backup-v3.

Program author: PB, pavel.bartos.pb@gmail.com

Git clone

Clone a project with standard Git on Linux or Windows:

git clone https://update.estudium.eu/git/eclone-server.git
git clone --branch v1.0.0 --single-branch --depth 1 https://update.estudium.eu/git/eclone-server.git

The project and each release show their exact command and a Copy button.

The main branch contains every project release in a directory named after its

version, for example ecast-pipe-server/0.9.8/README.md. Other versions sit

alongside it and remain present after git pull. A single wrapper directory

shared by every ZIP file is removed. A wrapper named after the project or the

project and version is also removed when only install.json sits beside it.

Both metadata and wrapped files then sit directly in the version directory,

for example eweb-server/0.8.10/README.md, without another eweb-server-0.8.10/.

Multiple top-level directories, other root files or conflicting names retain

their layout so that no file is overwritten. Original ZIPs and file

contents stay unchanged. Separately uploaded modules are not included.

The command beside each release downloads only that release. A vVERSION

tag contains only its VERSION directory and has no history of other releases.

The --single-branch --depth 1 options also limit transferred Git objects.

Using --branch alone selects the working tree but does not restrict fetching

other references. For example, 0.9.8 creates only ecast-pipe-server/0.9.8/

with that release's files. A version

that cannot be a Git tag uses release-ID, as shown by its clone command.

The public update API still selects the highest version with version_compare.

History is generated from published ZIPs, not original GitHub commits.

Paths containing .git are excluded from the Git export.

**After importing the corrected 1.7.7 backup, create a fresh clone into an empty

target directory.** Removing redundant wrappers changes the trees and commits

of affected releases and the main branch. Subsequent new releases can be

retrieved on main through git pull. A single-release

clone stays on that release; use another release's command and a free target

directory to download it separately.

Git reads each original release ZIP and verifies its SHA-256. It also works

when an eWeb restore omits extracted files in source/config (or config inside

an archive wrapper directory). The cache rebuilds on the next clone request;

this fix needs no cron job or additional configuration.

A missing or damaged original ZIP returns HTTP 503. Download diagnostics in

eUpdate Settings. The PHP log includes eUpdate git release with the release

and failure reason. Restore a known good backup or overwrite the affected

release with its verified original ZIP.