CTAN Comprehensive TeX Archive Network

Submitting to CTAN

This documentation describes version 1.1 of the API.

CTAN provides an interface to programmatically upload submissions. In contrast to the upload form this interface is documented and guaranteed to be supported in the foreseeable future.

The interface is versioned. Thus new features of the interface can be added without breaking the backward compatibility. This is achieved with new versions of the interface.

The interface uses standards of HTTP and HTML. This enables a Web front-end to make use of it directly.

Sending a Validation Request to CTAN

A validation request takes the parameters and applies the validation rules to it. It returns the result of the validation without doing anything else with the data provided. This means especially that the uploaded data is not processed as an upload and will not make it to the CTAN archive.

POST https://www.ctan.org/submit/validate

This URL receives validation requests.

  • The request body is multi-part.
  • The request body follows the encoding requirements of the "application/x-www-form-urlencoded" content type as defined by W3C.REC-html40-19980424.
  • The HTTP request header includes the "Content-Type" header field set to "application/x-www-form-urlencoded".

Parameters for Validation

field required length content
announcement optional 8192 This field contains the text for the announcement on the CTAN mailing list. If no text is present then no announcement will be sent.
author mandatory 128 This field contains the name or the names of the authors. Several authors can be separated by semicolon or several author fields can be specified.
bugs optional 255 This field contains the URL of the bug tracker for the package.
ctanPath optional 64 This field contains the proposed path in the CTAN archive. This is the part after /tex-archive when browsing the archive in the Web portal.
description mandatory 4096 This field contains an abstract description of the package.
email mandatory 255 This field contains the email address of the uploader.
home optional 255 The value of this field is the URL of the package's home page.
license mandatory 64 This field contains the licenses associated with the package or parts thereof. This field may be given several times to pass in several licenses.
mailinglist optional 255 This field contains the URL of the mailing list of the package.
note optional 2048 This field contains a note to the upload managers on CTAN. Any additional information which is useful for processing the upload or categorizing the package can be given here. The text is for communication purposes only. It is not shown publicly.
pkg mandatory 32 This field contains the name of the package. It consists of lower case letters, digits, the minus sign, or the underscore. The first character must be a lower-case letter.
repository optional 255 This field contains the URL of the package's repository.
summary mandatory 128 This field contains a short one-line description of the package.
topic optional 1024 This field contains the classification into topics of the catalogue. Several topics can be specified. The values returned by JSON List of Topics or XML List of Topics can be given as values. Other values are reported as warning. They have to be processed manually by a CTAN upload manager.
update mandatory 8 This field contains the value true if the package already exists on CTAN and false if it is a new package.
uploader mandatory 255 This field contains the name of the uploader. The uploader can be different from the author. In this case he needs to be permitted by an author to do so.
version mandatory 32 This field contains the version number of the package. No numbering scheme is imposed. An updated package must just have a different version number than the current version on CTAN.

In addition to the parameter fields described above one single archive file must be sent with the request. The name of this parameter compartment has to be file.

A file name has to be specified. It is used to determine the type of the archive. The archive file has be a zip archive with extension .zip or a gzipped tar archive with the extension .tgz or .tar.gz.

Return Status Codes for Validation

The HTTP status code signals the success or failure of the request. The following values can be expected:

200
This status code indicates success. The return value is a list in JSON notation which contains the warning and info items.
404
This status code indicates that an invalid request has been made. This can be caused by an invalid version number of the API or an invalid service method. The return body may contain further details.
409
This status code indicates that some inconsistencies have been found in the data or a technical error has occurred. The return body contains a list in JSON notation with the error, warning and info items.
500
This status code indicates an internal server error.

Return Values for Validation

The return value is a JSON list. This list contains the messages produced during the service operation.

["ERROR", "Archive access failed", <message>]
A technical error in accessing the archive has occurred. The <message> contains a description of the cause.
["ERROR", "Directory name invalid", <name>]
The archive contains a directory name which is not made up of ASCII letters, digits, the minus sign, or the underscore character.
["ERROR", "Empty directory", <directory>]
The archive contains an empty directory named <directory>.
["ERROR", "Empty field", <key>]
One of the mandatory fields is not present or has am empty value. <key> is the name of the field. It has one of the following values: author, bugs, description, email, home, license, mailinglist, note, pkg, summary, repository, topic, uploader, or version.
["ERROR", "Empty ins file", <filename>]
A file named <filename> has been encountered. It is considered to be a *.ins file but does not contain any text.
["ERROR", "Empty TDS archive", <tds>]
A file named <filename> has been encountered. It is considered to be a *.ins file but does not contain any text.
["ERROR", "Error reading TDS file", <tds>, <message>]
A technical error occurred while reading the TDS file <tds>. The message <message> may contain additional details.
["ERROR", "Field does not contains a URL", <key>, <value>]
The field value <value> for the field <key> does not contain a URL starting with http://, https://, ftp://, or mailto:.

The <key> is the name of the field as described in the section Parameters.

["ERROR", "Field too long", <key>, <value>, <max length>]
The field value <value> for the field <key> is too long to be stored in the CTAN database. The maximal length <max length> has been exceeded.

The <key> is the name of the field as described in the section Parameters.

["ERROR", "Illegal field value", <key>, <value>]
The field <key> has a value <value> which is not a simple string. This can for instance be the case if the field is given multiple times.

The following fields are supposed to be simple strings:

announcement, author, bugs, description, email, home, license, mailinglist, note, pkg, repository, topic, uploader, and version.

["ERROR", "Illegal package name", <package>]
The given package name <package> is not well-formed. It must start with a letter and consist of ASCII letters, digits, the minus sign, and the underscore character only.
["ERROR", "Illegal path in TDS", <tds>, <name>]
["ERROR", "Invalid API version", <api>]
The service is requested for a version number <api> which is not supported. Currently only version 1.0 is supported.
["ERROR", "Name contains special character", <name>]
The file with the name <name> does contain an unexpected character.
["ERROR", "Name contains special character in TDS", <tds>, <name>]
The file with the name <name> in the TDS <tds> archive does contain an unexpected character.
["ERROR", "Missing archive file"]
The service invocation does not contain the expected archive file.
["ERROR", "Missing field", <key>]
The mandatory field named <key> is missing or empty. See the parameter list for mandatory fields.
["ERROR", "Missing field value", <key>]

A field which is supposed to be present at least once has not been given. This can apply to the following fields:

author summary email pkg uploader version

["ERROR", "Missing PDF documentation"]
Any package is assumed to contain the documentation in form of a PDF file. This archive does not have any PDF file at all.
["ERROR", "Missing README in top level directory", <pkg>]
Any package is assumed to contain a README file in the top level package directory <pkg>. This file can have the name README or README.md. This archive does not have any README file in the package directory <pkg>.
["ERROR", "Missing top level directory", <pkg>]
The archive does not contain a proper top level directory named <pkg>.
["ERROR", "Multiple field values", <key>]

A field which is supposed to be present at most once has been encountered several times. This can apply to the following fields:

author description email pkg uploader version

["ERROR", "Package already exists", <package>]
The package <package> is declared as new package but a package with this name already exists.
["ERROR", "Remainder found", <type>, <file>]
Only files which can not be generated should be contained in the archive. The only exception is the documentation in PDF format.

The error is added if a generatable file or directory <file> is encountered. The <type> is the guess about the source of the generated file. It can take the following values:

"BibTeX"
*.blg and *.bbl as produced by
"compiler"
*.o, *.obj, and *.so as produced by native compilers
"ConTeXt"
*.tuc as produced by cont
"editor"
*.bak, *.swp, *~, and #* as produced by editors
"LaTeX"
*.brf, *.glg, *.glo, *.gls, *.loa, *.lof, *.lot, *.nav, *.out, *.tmp, *.toc, *.snm, *.vrb, and *.tuc as produced by
"LaTeX ins"
file which appears in a *.ins file as argument of \file or \generatedFile
"makeindex"
*.ind, *.ilg, and *.idx as produced by makeindex
"OS"
*.DS_Store and __MACOSX/* as produced by the operating system
"TeX"
*.aux, *.dvi, *.log, *.synctex, and *.synctex.gz as produced by
"version control"
*.gitignore, *.hgignore, *.hgtags, *.svnignore, .svn/*, .hg/*, .git/*, RCS/*, CVS/*
["ERROR", "Several top level directories"]
The archive contains several top level directories. It should contain only one such directory.
["ERROR", "Technical problem encountered. Please contact the web master"]
A technical error occurred during saving of the uploaded data.
["ERROR", "TDS read error"]
A technical error occurred during reading a TDS file.
["ERROR", "Unexpected top level directory", <directory>, <package>]
The archive contains a top level directory <directory> but the top level directory is expected to be identical to the package name <package>.
["ERROR", "Unknown archive type", <filename>]
An archive file has been encountered which does not have one of the recognized extensions:
.zip
The archive is assumed to be a ZIP file.
.tar.gz
The archive is assumed to be a tar archive compressed with gzip.
.tgz
The archive is assumed to be a tar archive compressed with gzip.

Other extensions and compressions are currently not supported.

["ERROR", "Updating non-existent package", <package>]
The package <package> is declared to be an update. But a package with this name does not exist in the CTAN catalogue.
["ERROR", "URL is not reachable", <type>, <url>]
The URL <url> given as value for <type> could not be reached. The type can be one of the following input field names:

home, support, announce, repository, development

["ERROR", "Version already exists", <package>, <version>]
The package <package> is declared to be an update. But the package version <version> is already installed on CTAN.
["WARNING", "CTAN path not found", <path>]
This warning is produced when the base directory of the CTAN path does not exist.
["WARNING", "Illegal CTAN path", <path>]
This warning is produced when the CTAN path is a top-level directory of the CTAN archive tree.
["WARNING", "Name does not start with a letter", <name>]
The archive contains a file <name> which does not start with a letter. Any file names must start with a letter.
["WARNING", "Package name discouraged", <package>]
This warning is produced when a package name is encountered which contains upper case letters. In this case the package name is silently translated to lower case.
["WARNING", "Topic not found", <topic>]
This warning is produced when a topic name is encountered which does not match with one of the known topics of CTAN.
["INFO", "TDS archive found", <tds>]
This info informs the caller that the archive <tds> is processed as TDS archive.
["INFO", "API version deprecated"]
This info informs the caller that the current version of the API is deprecated. A new version is already available. The migration to a more current version should be considered.

Sending a Submission Request to CTAN

The upload request validates the request parameters and passes the data to further processing by the CTAN team if no error has been detected. In case of an error the processing is stopped and nothing will make it to the CTAN archive. If no error is found then the upload is passed to the CTAN upload workflow.

POST https://www.ctan.org/submit/upload

  • The request body is multi-part.
  • The request body follows the encoding requirements of the "application/x-www-form-urlencoded" content type as defined by W3C.REC-html40-19980424.
  • The HTTP request header includes the "Content-Type" header field set to "application/x-www-form-urlencoded".

Parameters for Submission

The parameters for the upload request are the same as for the validate request; see section Parameters.

Return Status Codes for Submission

200
This status code indicates success. The return value is a list in JSON notation which contains the warning and info items.
404
This status code indicates that an invalid request has been made. This can be caused by an invalid version number of the API or an invalid service method. The return body may contain further details.
409
This status code indicates that some inconsistencies have been found in the data or a technical error has occurred. The return body contains a list in JSON notation with the error, warning and info items.
500
This status code indicates an internal server error.

Return Values for Submission

The return value is a JSON list. This list contains the messages produced during the service operation. The messages produced for the validation request described in section Return Values for Validation may appear here too. In addition the following messages might be returned:

["INFO", "Upload failed"]
This info indicates that the submission has failed.
["INFO", "Upload succeeded"]
This info indicates that the submission has succeeded.

Forcing an Invalid Upload

Sometimes it can be desirable to upload a package despite the fact that errors are contained. Be aware that this produces additional work load on the CTAN team. Thus don't do it without previous communication.

In such a case the note field should contain explanations about the expected errors and how to cope with them. Thus the length of the note field is taken as an indication whether some of the error messages should be degraded to warnings. Thus you can upload if your explanations are sufficiently large. Usually a few sentences are enough.

Please don't describe that there are errors. Instead describe why they are there and how the CTAN team should treat them.

Requesting the Known Fields

The known fields and their properties can be requested with a HTTP request to the following URL without any further parameters:

POST https://www.ctan.org/submit/fields

The request returns a JSON map of the known fields. The key of the map is the name of the field. The value is a map with properties of this field.

text
The value is a short text in English describing the field.
nullable
The value is true if the field can be omitted. Otherwise the value is false.
maxsize
The value is a number which is the maximal length of the field's value.
blank
The value is true if the field can be the empty string. Otherwise the value is false.
email
The value is true if the field is supposed to contain a valid email address. Otherwise the value is false.
file
The value is true if the field contains an uploaded file. Otherwise the value is false.

Example

{"pkg":     {"text":     "CTAN id of the package",
             "nullable": false,
             "maxsize":  32},
 "version": {"text":     "version of the package",
             "nullable": false,
             "maxsize":  32},
 "author":  {"text":     "name of the author(s)",
             "nullable": false,
             "maxsize":  128},
...
}

Guest Book Sitemap Contact Contact Author