StackHub Bulletin BoardAdvertise your announcements here!


StackHub REST Interface


StackHub exposes a small Haystack compliant REST API for accessing data on packages and package versions.

The base URL to all StackHub REST operations is:

Zinc vs JZON

The API defaults to reading and writing Zinc but is also capable of reading and writing JZON (JSON encoded Zinc).

Following HTTP standards, the Content-Type HTTP request header is used to specify the format of request data, and the Accept header is used to specify the format that data should be returned in. Note they do not need to be the same!

To have response data formatted in JZON, you can also give the URL an extension of .json. Likewise, an extension of .zinc ensures the response is formatted as Zinc.

Note that URL query string parameters override input row data. This, combined with a .json extension, makes it easy to test operations from an internet browser.

Example HTTP Headers:

To send data formatted as Zinc:

  Content-Type: text/zinc

To send data formatted as JZON:

  Content-Type: application/json

For response data formatted as Zinc:

  Accept: text/zinc; q=1.0

For response data formatted as JZON:

  Accept: application/json; q=1.0


Authentication is required to view and download private packages. StackHub uses Basic HTTP Authentication and the Authorization HTTP header. The header should be set to:

  Authorization: Basic <SecretKey>

Where SecretKey is the Base64 encoding of the string <email>:<password>.

Basic HTTP Authentication example:

An email of and a password of secret should produce the following HTTP header:

  Authorization: Basic Ym9iQGFjbWUuY29tOnNlY3JldA==


A Package is a unique name that represents all the related package versions / files.

Packages are made up from the following data:

NameHaystack TypeDescription
packageMarkerAlways present
idReferenceSystem identifier
disStringDisplay string; same as name
nameStringThe unique name of the package
summaryStringA brief package description
orgRefReferenceThe owning organization
createdTsDateTimeWhen the package was created
createdByRefReferenceWho created the package
vcsURI(Optional) URL to the package's public repository
licenseString(Optional) The SPDX license id the package is distributed under
latestVersionStringThe latest pacakge version
latestVersionStatusStringMay be either alpha, beta, or released
isDownloadableBoolIs true if the authenticated user is authorised to download package versions
tagNamesList of StringsList of package tags applied to this package

Example package formatted in JZON:

  "package"             : "m:",
  "id"                  : "r:fbb7fa59-8a69-4fb1-a15a-87e44e1c70ac",
  "dis"                 : "sfxCalculusExt",
  "name"                : "sfxCalculusExt",
  "summary"             : "Use Calculus on History Grids in SkySpark",
  "orgRef"              : "r:6f28b566-2e97-4311-9e30-10472bca4651 SkyFoundry",
  "createdTs"           : "t:2015-12-09T22:10:13.845Z UTC",
  "createdByRef"        : "r:f18bc1bf-66a6-4570-8e8e-7ef00d25ee40 Adam Wallen",
  "vcs"                 : "u:",
  "license"             : "MIT",
  "latestVersion"       : "1.2.0",
  "isDownloadable"      : true,
  "tagNames"            : ["tag1", "tag2"],


A general purpose read operation for finding packages.

Only one input row is allowed which should contain either id,nameorsearch

search should be a space separated list of keywords. Keywords are searched for in a package's name, summary, and its latest read me. skip and limit are only valid during keyword searches.

NameHaystack TypeDescription
idReferenceA package reference
nameStringA package name
searchStringKeywords to search for
skipNumber(Optional) The number of rows that should be skipped
limitNumber(Optional) The maximum number of rows to return

Packages are returned in alphabetical package name order.

packageRead responds to GET and POST requests.

Example URL requests:

$ wget \
$ wget \
$ wget \
   ?search="calculus" \
   &skip=0 \

Example JZON request:

  "rows" : [
      "search" : "calculus",
      "skip"   : 0,
      "limit"  : 10

Package Versions

A package version represents an uploaded package file.

Package versions are made up from the following data:

NameHaystack TypeDescription
packageVersionMarkerAlways present
idReferenceSystem identifier
disStringDisplay string; <packageName> <version>
packageRefReferenceThe containing package
packageNameStringThe package name
versionStringThe package version
releaseStatusStringMay be either alpha, beta, or released
orgRefReferenceThe organization who owns the package
publishedTsDateTimeThe date the package file was published
publishedByRefReferenceThe user who published the package file
buildTsDateTimeThe date the package file was built
isFanPodBooltrue if the file is a Fantom Pod
isAxModuleBooltrue if the file is a Niagara AX Module
fanDependsString(Optional) A list of Fantom dependencies
axDependsString(Optional) A list of AX module dependencies
fileNameStringThe original name the file was uploaded with
fileSizeNumberSize of the pacakge file in bytes
fileMd5StringMD5 hash of the package file
fileSha1StringSHA1 hash of the package file
downloadUrlURIThe URL where the package version may be download from

Example package version formatted in JZON:

     "packageVersion" : "m:",
     "id"             : "r:260a25fb-7aca-4e0c-bdd8-7654dd5a5d22",
     "dis"            : "sfxCalculusExt 1.0",
     "packageRef"     : "r:fbb7fa59-8a69-4fb1-a15a-87e44e1c70ac sfxCalculusExt",
     "packageName"    : "sfxCalculusExt",
     "version"        : "1.0",
     "releaseStatus"  : "released",
     "orgRef"         : "r:6f28b566-2e97-4311-9e30-10472bca4651 SkyFoundry",
     "publishedTs"    : "t:2015-12-10T03:56:34.935Z UTC",
     "publishedByRef" : "r:f18bc1bf-66a6-4570-8e8e-7ef00d25ee40 Adam Wallen",
     "buildTs"        : "t:2015-12-10T03:44:59.147Z UTC",
     "isFanPod"       : "true",
     "isAxModule"     : "false",
     "fanDepends"     : "sys 1.0;haystack 2.1;proj 2.1",
     "fileName"       : "sfxCalculusExt.pod",
     "fileSize"       : 2187,
     "fileMd5"        : "6cbd0c08ffbba95f1da87e029f9d0807",
     "fileSha1"       : "2a85d66e744c795da0d72f45f0186eb81e29f826"
     "downloadUrl"    : "u:"


A read operation that returns package versions. This operation takes one input row which should contain either id or name. name may also (optionally) specify a version number, such as:

  sfxCalculusExt 1.0.2

Or a range of versions, for example:

  sfxCalculusExt 1.0.2 - 1.0

The range format is the same as described by Fantom's Depend class.

NameHaystack TypeDescription
idReferenceA package version reference
nameStringA package name
limitNumber(Optional) The maximum number of rows to return

Packages are returned in descending version order. This ensures the latest package version is always returned first.

packageVersionRead responds to GET and POST requests.

Example URL requests:

$ wget \
$ wget \
   ?name="sfxCalculusExt 1.0.2 - 1.0" \

Example JZON request:

  "rows" : [
      "name"  : "sfxCalculusExt",
      "limit" : 5


This operation uploads and publishes a package file and returns the newly created package version.

This operation differs from most in that the content type should be multipart/form-data, and consist of two parts. The first part, named grid, contains the input row used to specify values. The second part, named package, is the actual package version file.

If uploading a Fantom pod file, or an AX module, then StackHub parses all necessary meta from the file itself. releaseStatus is optional and defaults to released if not given.

If uploading any other file, then name, version, and buildTs need to be supplied.

All calls to packageVersionCreate must be authenticated.

NameHaystack TypeDescription
releaseStatusString(Optional) May be either alpha, beta, or released.
nameString(Optional) The package name
versionString(Optional) The package file version
buildTsDateTime(Optional) The build timestamp

packageVersionCreate responds to POST requests.

Note that if manually creating meta.props for a Fantom pod, the buildTs property has to be in Fantom's DateTime.toStr() format. In particular a trailing time zone of Z is invalid. Instead you must specify Z UTC, as in:

  2016-08-22T21:36:21.949Z UTC

Sample Fantom code, using the Butter library, that uploads a package file:

using afButter

apiUrl   := ``
pkgFile  := `/C:/myPackageFile.pod`.toFile
inputRow := ["releaseStatus" : "beta"]
secret   := "<email>:<password>".toBuf.toBase64

request  := ButterRequest(apiUrl) {
    it.headers.authorization = "Basic $secret"
}.writeMultipartForm |form| {
    form.writeJsonObj("grid", ["rows":[inputRow]])
    form.writeFile("package", pkgFile)


Package files may be downloaded from the URL given in the corresponding package version.

To download a private package file, the request must contain authentication credentials.

Standard Haystack Ops

The StackHub API also contains some standard Haystack operations.


Returns basic server information.

Example URL request:

$ wget

Sample JZON response:

  "haystackVersion" : "3.0",
  "tz"              : "Etc/UTC",
  "serverName"      : "ip-172-31-28-34",
  "serverTime"      : "t:2016-08-23T15:09:39.328Z UTC",
  "serverBootTime"  : "t:2016-08-17T21:58:55.761Z UTC",
  "productName"     : "StackHub",
  "productVersion"  : "",
  "productUri"      : "u:",
  "moduleName"      : "StackHub Website",
  "moduleVersion"   : "",
  "environment"     : "PRODUCTION",
  "vendorName"      : "StackHub LLC",
  "vendorUri"       : "u:"


Returns which MIME types are available to read and write grids.

Example URL request:

$ wget

Sample JZON response:

  "meta" : {"count": 4},
  "rows" : [
    {"mime": "application/json",    "send": "m:", "receive": "m:" },
    {"mime": "multipart/form-data", "send": null, "receive": "m:" },
    {"mime": "text/zinc",           "send": "m:", "receive": "m:" },
    {"mime": "text/plain",          "send": "m:", "receive": "m:" }


Returns a list of available operations on the server.

Example URL request:

$ wget

Sample JZON response:

  "meta" : {"count": 6},
  "rows" : [
    {"name": "2.0/about",                "summary": "Summary information about the server"},
    {"name": "2.0/formats",              "summary": "Grid data formats supported by this server"},
    {"name": "2.0/ops",                  "summary": "Operations supported by this server"},
    {"name": "2.0/packageRead",          "summary": "Reads package records."},
    {"name": "2.0/packageVersionCreate", "summary": "Creates a package version record."},
    {"name": "2.0/packageVersionRead",   "summary": "Reads package version records."}