CTAN Comprehensive TeX Archive Network

Sub­mit­ting to CTAN

This doc­u­men­ta­tion de­scribes ver­sion 1.1 of the API.

CTAN pro­vides an in­ter­face to pro­gram­mat­i­cally up­load sub­mis­sions. In con­trast to the up­load form this in­ter­face is doc­u­mented and guar­an­teed to be sup­ported in the fore­see­able fu­ture.

The in­ter­face is ver­sioned. Thus new fea­tures of the in­ter­face can be added with­out break­ing the back­ward com­pat­i­bil­ity. This is achieved with new ver­sions of the in­ter­face.

The in­ter­face uses stan­dards of HTTP and HTML. This en­ables a Web front-end to make use of it di­rectly.

Send­ing a Val­i­da­tion Re­quest to CTAN

A val­i­da­tion re­quest takes the pa­ram­e­ters and ap­plies the val­i­da­tion rules to it. It re­turns the re­sult of the val­i­da­tion with­out do­ing any­thing else with the data pro­vided. This means es­pe­cially that the up­loaded data is not pro­cessed as an up­load and will not make it to the CTAN archive.

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

This URL re­ceives val­i­da­tion re­quests.

  • The re­quest body is multi-part.
  • The re­quest body fol­lows the en­cod­ing re­quire­ments of the "application/x-www-form-urlencoded" con­tent type as de­fined by W3C.REC-htm­l40-19980424.
  • The HTTP re­quest header in­cludes the "Content-Type" header field set to "application/x-www-form-urlencoded".

Pa­ram­e­ters for Val­i­da­tion

field re­quired length con­tent
announcement op­tional 8192 This field con­tains the text for the an­nounce­ment on the CTAN mail­ing list. If no text is present then no an­nounce­ment will be sent.
author manda­tory 128 This field con­tains the name or the names of the au­thors. Sev­eral au­thors can be sep­a­rated by semi­colon or sev­eral au­thor fields can be spec­i­fied.
bugtracker op­tional 255 This field con­tains the URL of the bug tracker for the pack­age.
ctanPath op­tional 64 This field con­tains the pro­posed path in the CTAN archive. This is the part af­ter /tex-archive when brows­ing the archive in the Web por­tal.
description manda­tory 4096 This field con­tains an ab­stract de­scrip­tion of the pack­age.
email manda­tory 255 This field con­tains the email ad­dress of the up­loader.
home op­tional 255 The value of this field is the URL of the pack­age's home page.
license manda­tory 64 This field con­tains the li­censes as­so­ci­ated with the pack­age or parts thereof. This field may be given sev­eral times to pass in sev­eral li­censes.
mailinglist op­tional 255 This field con­tains the URL of the mail­ing list of the pack­age.
note op­tional 2048 This field con­tains a note to the up­load man­agers on CTAN. Any ad­di­tional in­for­ma­tion which is use­ful for pro­cess­ing the up­load or cat­e­go­riz­ing the pack­age can be given here. The text is for com­mu­ni­ca­tion pur­poses only. It is not shown pub­licly.
pkg manda­tory 32 This field con­tains the name of the pack­age. It con­sists of lower case let­ters, dig­its, the mi­nus sign, or the un­der­score. The first char­ac­ter must be a lower-case let­ter.
repository op­tional 255 This field con­tains the URL of the pack­age's repos­i­tory.
summary manda­tory 128 This field con­tains a short one-line de­scrip­tion of the pack­age.
topic op­tional 1024 This field con­tains the clas­si­fi­ca­tion into top­ics of the cat­a­logue. Sev­eral top­ics can be spec­i­fied. The val­ues re­turned by JSON List of Topics or XML List of Topics can be given as val­ues. Other val­ues are re­ported as warn­ing. They have to be pro­cessed man­u­ally by a CTAN up­load man­ager.
update manda­tory 8 This field con­tains the value true if the pack­age al­ready ex­ists on CTAN and false if it is a new pack­age.
uploader manda­tory 255 This field con­tains the name of the up­loader. The up­loader can be dif­fer­ent from the au­thor. In this case he needs to be per­mit­ted by an au­thor to do so.
version manda­tory 32 This field con­tains the ver­sion num­ber of the pack­age. No num­ber­ing scheme is im­posed. An up­dated pack­age must just have a dif­fer­ent ver­sion num­ber than the cur­rent ver­sion on CTAN.

In ad­di­tion to the pa­ram­e­ter fields de­scribed above one sin­gle archive file must be sent with the re­quest. The name of this pa­ram­e­ter com­part­ment has to be file.

A file name has to be spec­i­fied. It is used to de­ter­mine the type of the archive. The archive file has be a zip archive with ex­ten­sion .zip or a gzipped tar archive with the ex­ten­sion .tgz or .tar.gz.

Re­turn Sta­tus Codes for Val­i­da­tion

The HTTP sta­tus code sig­nals the suc­cess or fail­ure of the re­quest. The fol­low­ing val­ues can be ex­pected:

200
This sta­tus code in­di­cates suc­cess. The re­turn value is a list in JSON no­ta­tion which con­tains the warn­ing and info items.
404
This sta­tus code in­di­cates that an in­valid re­quest has been made. This can be caused by an in­valid ver­sion num­ber of the API or an in­valid ser­vice method. The re­turn body may con­tain fur­ther de­tails.
409
This sta­tus code in­di­cates that some in­con­sis­ten­cies have been found in the data or a tech­ni­cal er­ror has oc­curred. The re­turn body con­tains a list in JSON no­ta­tion with the er­ror, warn­ing and info items.
500
This sta­tus code in­di­cates an in­ter­nal server er­ror.

Re­turn Values for Val­i­da­tion

The re­turn value is a JSON list. This list con­tains the mes­sages pro­duced dur­ing the ser­vice op­er­a­tion.

["ERROR", "Archive ac­cess failed", <mes­sage>]
A tech­ni­cal er­ror in ac­cess­ing the archive has oc­curred. The <mes­sage> con­tains a de­scrip­tion of the cause.
["ERROR", "Direc­tory name in­valid", <name>]
The archive con­tains a di­rec­tory name which is not made up of ASCII let­ters, dig­its, the mi­nus sign, or the un­der­score char­ac­ter.
["ERROR", "Empty di­rec­tory", <di­rec­tory>]
The archive con­tains an empty di­rec­tory named <di­rec­tory>.
["ERROR", "Empty field", <key>]
One of the manda­tory fields is not present or has am empty value. <key> is the name of the field. It has one of the fol­low­ing val­ues: author, bugtracker, description, email, home, license, mailinglist, note, pkg, summary, repository, topic, uploader, or version.
["ERROR", "Empty ins file", <file­name>]
A file named <file­name> has been en­coun­tered. It is con­sid­ered to be a *.ins file but does not con­tain any text.
["ERROR", "Empty TDS archive", <tds>]
A file named <file­name> has been en­coun­tered. It is con­sid­ered to be a *.ins file but does not con­tain any text.
["ERROR", "Er­ror read­ing TDS file", <tds>, <mes­sage>]
A tech­ni­cal er­ror oc­curred while read­ing the TDS file <tds>. The mes­sage <mes­sage> may con­tain ad­di­tional de­tails.
["ERROR", "Field does not con­tains a URL", <key>, <value>]
The field value <value> for the field <key> does not con­tain a URL start­ing with http://, https://, ftp://, or mailto:.

The <key> is the name of the field as de­scribed in the sec­tion Pa­ram­e­ters.

["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 max­i­mal length <max length> has been ex­ceeded.

The <key> is the name of the field as de­scribed in the sec­tion Pa­ram­e­ters.

["ERROR", "Il­le­gal field value", <key>, <value>]
The field <key> has a value <value> which is not a sim­ple string. This can for in­stance be the case if the field is given mul­ti­ple times.

The fol­low­ing fields are sup­posed to be sim­ple strings:

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

["ERROR", "Il­le­gal pack­age name", <pack­age>]
The given pack­age name <pack­age> is not well-formed. It must start with a let­ter and con­sist of ASCII let­ters, dig­its, the mi­nus sign, and the un­der­score char­ac­ter only.
["ERROR", "Il­le­gal path in TDS", <tds>, <name>]
["ERROR", "In­valid API ver­sion", <api>]
The ser­vice is re­quested for a ver­sion num­ber <api> which is not sup­ported. Cur­rently only ver­sion 1.0 is sup­ported.
["ERROR", "Name con­tains spe­cial char­ac­ter", <name>]
The file with the name <name> does con­tain an un­ex­pected char­ac­ter.
["ERROR", "Name con­tains spe­cial char­ac­ter in TDS", <tds>, <name>]
The file with the name <name> in the TDS <tds> archive does con­tain an un­ex­pected char­ac­ter.
["ERROR", "Miss­ing archive file"]
The ser­vice in­vo­ca­tion does not con­tain the ex­pected archive file.
["ERROR", "Miss­ing field", <key>]
The manda­tory field named <key> is miss­ing or empty. See the pa­ram­e­ter list for manda­tory fields.
["ERROR", "Miss­ing field value", <key>]

A field which is sup­posed to be present at least once has not been given. This can ap­ply to the fol­low­ing fields:

author summary email pkg uploader version

["ERROR", "Miss­ing PDF doc­u­men­ta­tion"]
Any pack­age is as­sumed to con­tain the doc­u­men­ta­tion in form of a PDF file. This archive does not have any PDF file at all.
["ERROR", "Miss­ing README in top level di­rec­tory", <pkg>]
Any pack­age is as­sumed to con­tain a README file in the top level pack­age di­rec­tory <pkg>. This file can have the name README or README.md. This archive does not have any README file in the pack­age di­rec­tory <pkg>.
["ERROR", "Miss­ing top level di­rec­tory", <pkg>]
The archive does not con­tain a proper top level di­rec­tory named <pkg>.
["ERROR", "Mul­ti­ple field val­ues", <key>]

A field which is sup­posed to be present at most once has been en­coun­tered sev­eral times. This can ap­ply to the fol­low­ing fields:

author description email pkg uploader version

["ERROR", "Pack­age al­ready ex­ists", <pack­age>]
The pack­age <pack­age> is de­clared as new pack­age but a pack­age with this name al­ready ex­ists.
["ERROR", "Re­main­der found", <type>, <file>]
Only files which can not be gen­er­ated should be con­tained in the archive. The only ex­cep­tion is the doc­u­men­ta­tion in PDF for­mat.

The er­ror is added if a gen­er­at­able file or di­rec­tory <file> is en­coun­tered. The <type> is the guess about the source of the gen­er­ated file. It can take the fol­low­ing val­ues:

"BibTeX"
*.blg and *.bbl as pro­duced by BibTeX
"com­piler"
*.o, *.obj, and *.so as pro­duced by na­tive com­pil­ers
"ConTeXt"
*.tuc as pro­duced by cont
"ed­i­tor"
*.bak, *.swp, *~, and #* as pro­duced by ed­i­tors
"LaTeX"
*.brf, *.glg, *.glo, *.gls, *.loa, *.lof, *.lot, *.nav, *.out, *.tmp, *.toc, *.snm, *.vrb, and *.tuc as pro­duced by
"LaTeX ins"
file which ap­pears in a *.ins file as ar­gu­ment of \file or \generatedFile
"makein­dex"
*.ind, *.ilg, and *.idx as pro­duced by makein­dex
"OS"
*.DS_Store and __MACOSX/* as pro­duced by the op­er­at­ing sys­tem
"TeX"
*.aux, *.dvi, *.log, *.sync­tex, and *.sync­tex.gz as pro­duced by
"ver­sion con­trol"
*.git­ig­nore, *.hgig­nore, *.hg­tags, *.svnig­nore, .svn/*, .hg/*, .git/*, RCS/*, CVS/*
["ERROR", "Sev­eral top level di­rec­to­ries"]
The archive con­tains sev­eral top level di­rec­to­ries. It should con­tain only one such di­rec­tory.
["ERROR", "Tech­ni­cal prob­lem en­coun­tered. Please con­tact the web mas­ter"]
A tech­ni­cal er­ror oc­curred dur­ing sav­ing of the up­loaded data.
["ERROR", "TDS read er­ror"]
A tech­ni­cal er­ror oc­curred dur­ing read­ing a TDS file.
["ERROR", "Un­ex­pected top level di­rec­tory", <di­rec­tory>, <pack­age>]
The archive con­tains a top level di­rec­tory <di­rec­tory> but the top level di­rec­tory is ex­pected to be iden­ti­cal to the pack­age name <pack­age>.
["ERROR", "Un­known archive type", <file­name>]
An archive file has been en­coun­tered which does not have one of the rec­og­nized ex­ten­sions:
.zip
The archive is as­sumed to be a ZIP file.
.tar.gz
The archive is as­sumed to be a tar archive com­pressed with gzip.
.tgz
The archive is as­sumed to be a tar archive com­pressed with gzip.

Other ex­ten­sions and com­pres­sions are cur­rently not sup­ported.

["ERROR", "Up­dat­ing non-ex­is­tent pack­age", <pack­age>]
The pack­age <pack­age> is de­clared to be an up­date. But a pack­age with this name does not ex­ist in the CTAN cat­a­logue.
["ERROR", "URL is not reach­able", <type>, <url>]
The URL <url> given as value for <type> could not be reached. The type can be one of the fol­low­ing in­put field names:

home, support, announce, repository, development

["ERROR", "Ver­sion al­ready ex­ists", <pack­age>, <ver­sion>]
The pack­age <pack­age> is de­clared to be an up­date. But the pack­age ver­sion <ver­sion> is al­ready in­stalled on CTAN.
["WARNING", "CTAN path not found", <path>]
This warn­ing is pro­duced when the base di­rec­tory of the CTAN path does not ex­ist.
["WARNING", "Il­le­gal CTAN path", <path>]
This warn­ing is pro­duced when the CTAN path is a top-level di­rec­tory of the CTAN archive tree.
["WARNING", "Name does not start with a let­ter", <name>]
The archive con­tains a file <name> which does not start with a let­ter. Any file names must start with a let­ter.
["WARNING", "Pack­age name dis­cour­aged", <pack­age>]
This warn­ing is pro­duced when a pack­age name is en­coun­tered which con­tains up­per case let­ters. In this case the pack­age name is silently trans­lated to lower case.
["WARNING", "Topic not found", <topic>]
This warn­ing is pro­duced when a topic name is en­coun­tered which does not match with one of the known top­ics of CTAN.
["INFO", "TDS archive found", <tds>]
This info in­forms the caller that the archive <tds> is pro­cessed as TDS archive.
["INFO", "API ver­sion dep­re­cated"]
This info in­forms the caller that the cur­rent ver­sion of the API is dep­re­cated. A new ver­sion is al­ready avail­able. The mi­gra­tion to a more cur­rent ver­sion should be con­sid­ered.

Send­ing a Sub­mis­sion Re­quest to CTAN

The up­load re­quest val­i­dates the re­quest pa­ram­e­ters and passes the data to fur­ther pro­cess­ing by the CTAN team if no er­ror has been de­tected. In case of an er­ror the pro­cess­ing is stopped and noth­ing will make it to the CTAN archive. If no er­ror is found then the up­load is passed to the CTAN up­load work­flow.

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

  • The re­quest body is multi-part.
  • The re­quest body fol­lows the en­cod­ing re­quire­ments of the "application/x-www-form-urlencoded" con­tent type as de­fined by W3C.REC-htm­l40-19980424.
  • The HTTP re­quest header in­cludes the "Content-Type" header field set to "application/x-www-form-urlencoded".

Pa­ram­e­ters for Sub­mis­sion

The pa­ram­e­ters for the up­load re­quest are the same as for the val­i­date re­quest; see sec­tion Pa­ram­e­ters.

Re­turn Sta­tus Codes for Sub­mis­sion

200
This sta­tus code in­di­cates suc­cess. The re­turn value is a list in JSON no­ta­tion which con­tains the warn­ing and info items.
404
This sta­tus code in­di­cates that an in­valid re­quest has been made. This can be caused by an in­valid ver­sion num­ber of the API or an in­valid ser­vice method. The re­turn body may con­tain fur­ther de­tails.
409
This sta­tus code in­di­cates that some in­con­sis­ten­cies have been found in the data or a tech­ni­cal er­ror has oc­curred. The re­turn body con­tains a list in JSON no­ta­tion with the er­ror, warn­ing and info items.
500
This sta­tus code in­di­cates an in­ter­nal server er­ror.

Re­turn Values for Sub­mis­sion

The re­turn value is a JSON list. This list con­tains the mes­sages pro­duced dur­ing the ser­vice op­er­a­tion. The mes­sages pro­duced for the val­i­da­tion re­quest de­scribed in sec­tion Re­turn Values for Val­i­da­tion may ap­pear here too. In ad­di­tion the fol­low­ing mes­sages might be re­turned:

["INFO", "Upload failed"]
This info in­di­cates that the sub­mis­sion has failed.
["INFO", "Upload suc­ceeded"]
This info in­di­cates that the sub­mis­sion has suc­ceeded.

Forc­ing an In­valid Upload

Some­times it can be de­sir­able to up­load a pack­age de­spite the fact that er­rors are con­tained. Be aware that this pro­duces ad­di­tional work load on the CTAN team. Thus don't do it with­out pre­vi­ous com­mu­ni­ca­tion.

In such a case the note field should con­tain ex­pla­na­tions about the ex­pected er­rors and how to cope with them. Thus the length of the note field is taken as an in­di­ca­tion whether some of the er­ror mes­sages should be de­graded to warn­ings. Thus you can up­load if your ex­pla­na­tions are suf­fi­ciently large. Usu­ally a few sen­tences are enough.

Please don't de­scribe that there are er­rors. In­stead de­scribe why they are there and how the CTAN team should treat them.

Re­quest­ing the Known Fields

The known fields and their prop­er­ties can be re­quested with a HTTP re­quest to the fol­low­ing URL with­out any fur­ther pa­ram­e­ters:

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

The re­quest re­turns a JSON map of the known fields. The key of the map is the name of the field. The value is a map with prop­er­ties of this field.

text
The value is a short text in English de­scrib­ing the field.
nul­lable
The value is true if the field can be omit­ted. Other­wise the value is false.
max­size
The value is a num­ber which is the max­i­mal length of the field's value.
blank
The value is true if the field can be the empty string. Other­wise the value is false.
email
The value is true if the field is sup­posed to con­tain a valid email ad­dress. Other­wise the value is false.
file
The value is true if the field con­tains an up­loaded file. Other­wise the value is false.

Ex­am­ple

{"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