General documentation / cheat sheets for various languages and services

registry.npmjs.org

http://registry.npmjs.org/ is a CouchDB endpoint, but doesn't support /_utils/ navigation.

http://registry.npmjs.org/

{ db_name: "registry", doc_count: 116761, doc_del_count: 378, update_seq: 305896, purge_seq: 0, compact_running: false, disk_size: 672571515, data_size: 420639278, instance_start_time: "1413839504850820", disk_format_version: 6, committed_update_seq: 305896 }

http://registry.npmjs.org/-/all

This pulls down a huge ~85 MB one-line JSON file. The keys are the package names, and they are alphabetically sorted. It's pretty speedy, though — I get 30+ MB/s when calling it from a Linode.

{ "_updated": 1417985649051, ... "amulet": { "name": "amulet", "description": "As-soon-as-possible streaming async mustache templating", "dist-tags": { "latest": "1.0.7" }, "maintainers": [ { "name": "chbrown", "email": "io@henrian.com" } ], "author": { "name": "Christopher Brown", "email": "io@henrian.com", "url": "http://henrian.com" }, "repository": { "type": "git", "url": "git://github.com/chbrown/amulet.git" }, "time": { "modified": "2014-01-14T03:24:23.968Z" }, "versions": { "1.0.7": "latest" }, "keywords": [ "template", "mustache", "mu", "asynchronous", "streaming", "nodeps" ] }, ... "flickr-with-uploads": { "name": "flickr-with-uploads", "description": "Flickr API with OAuth 1.0A and uploads", "dist-tags": { "latest": "2.0.4" }, "maintainers": [ { "name": "chbrown", "email": "io@henrian.com" } ], "repository": { "type": "git", "url": "git://github.com/chbrown/flickr-with-uploads.git" }, "author": { "name": "Christopher Brown", "email": "io@henrian.com", "url": "http://henrian.com" }, "homepage": "https://github.com/chbrown/flickr-with-uploads", "keywords": [ "flickr", "api", "oauth", "upload", "backup", "archive", "sync" ], "contributors": [ { "name": "Sujal Shah", "email": "codesujal@gmail.com" }, { "name": "Thomas", "url": "https://github.com/tomap" }, { "name": "Tomasz Kołodziejski", "url": "https://github.com/neojski" } ], "bugs": { "url": "https://github.com/chbrown/flickr-with-uploads/issues", "email": "Christopher Brown " }, "license": "MIT", "readmeFilename": "README.md", "time": { "modified": "2014-05-02T17:46:51.354Z" }, "versions": { "2.0.4": "latest" } }, ... }

You can use the /since path to get updates, instead of the full file. (See lib/cache/update-index.js in the npm source code for usage.) For example:

https://registry.npmjs.org/-/all/since?stale=update_after&startkey=1431729476513

This will respond with an HTTP 302 redirect, depending on how long ago startkey is. startkey is just the date you want to get updates after, represented as the number of milliseconds since the epoch, i.e., what new Date().getTime() returns.

Here are some example Location's it responds with:

Or it may respond with a server failure; apparently it doesn't just resolve a time difference to a specific name.

http://registry.npmjs.org/-/by-user/chbrown|isaacs

{ "chbrown": [ "adts", "amulet", "autoauth", "birdy", "brew-tour", "cameo", "cameo-crawler", "cameo-twitter", "domlike", "dropyll", "fapply", "flickr-sync", "flickr-with-uploads", "fs-change", "gzbz", "http-enhanced", "iwc", "jsed", "json-cmd", "less-watch", "lexicons", "loge", "node_restarter", "npm-search-downloads", "osx-notifier", "parallel-wget", "ranges", "regex-router", "rfc6902", "ruthless", "sqlcmd", "streaming", "sv", "tex", "turk", "twilight", "visible", "winston-notification-center", "xmlconv", "yaml2sql" ], "isaacs": [ "abbrev", "asshole", "async-cache", "bench", "bitch", "block-stream", "brace-expansion", "callback-tracker", "canonical-host", "char-spinner", "chmodr", "chownr", "cluster-callresp", "cluster-master", "cocksucker", "coffee-cleanse", "coffeescript", "config-chain", "core-util-is", "couch-login", "couch-readonly-replica", "couchdb-log-parse", "csrf-lite", "cunt", "cuttlefish", "dezalgo", "domain-http-server", "duplex-passthrough", "eliza", "emcee", "error-page", "fag", "faggot", "fast-list", "fastly", "filewatcherthing", "fs-write-stream-atomic", "fstream", "fstream-ignore", "fstream-npm", "ghlink", "gist-cli", "github-flavored-markdown", "glob", "graceful-fs", "gyp-reader", "hardhttps", "hexedit", "http-agent", "http-https", "inflight", "inherits", "ini", "init-package-json", "irssi-questions", "json-stringify-safe", "lockfile", "lru-cache", "lylog", "manta-client", "mcouch", "minimatch", "multi-fs", "mute-stream", "nave", "nigger", "node", "node-date", "node-gyp", "node-strict", "noexit", "nopt", "normalize-package-data", "nosync", "npm", "npm-cache-dir", "npm-cache-filename", "npm-docsite", "npm-expansions", "npm-fullfat-registry", "npm-install-checks", "npm-intro-slides", "npm-package-arg", "npm-registry-client", "npm-registry-couchapp", "npm-registry-readme-trim", "npm-skim-registry", "npm-user-validate", "npm-www", "npmconf", "npmjs.org", "npmlog", "once", "osenv", "parse-json-response", "penis", "penis.js", "pingme", "promzard", "proto-list", "read", "read-installed", "read-package-json", "read-package-tree", "readable-stream", "readdir-scoped-modules", "redsess", "rimraf", "sax", "semicolons", "semver", "seq-file", "server-destroy", "sigmund", "simple-protocol", "slide", "sodn", "srand", "ssh-key-decrypt", "st", "stream-multiplexer", "streams2", "tako-cookies", "tako-session-token", "tap", "tap-assert", "tap-consumer", "tap-global-harness", "tap-harness", "tap-producer", "tap-results", "tap-runner", "tap-test", "tar", "tcp", "templar", "tesla.svc.core.routes", "touch", "truncating-stream", "tt", "udp", "uid-number", "underscorify", "use-strict", "util-extend", "voxer-blog-demo", "which", "wrappy", "yamlish" ] }

http://registry.npmjs.org/-/user/org.couchdb.user:chbrown

{ "_id": "org.couchdb.user:chbrown", "_rev": "5-8622978234df9353110443726e862552", "fullname": "Christopher Brown", "fields": [ { "name": "fullname", "value": "Christopher Brown", "title": "Full Name", "show": "Christopher Brown" }, { "name": "email", "value": "io@henrian.com", "title": "Email", "show": "<a href=\"mailto:io@henrian.com\">io@henrian.com</a>" }, { "name": "github", "value": "https://github.com/chbrown", "title": "Github", "show": "<a rel=\"me\" href=\"https://github.com/https://github.com/chbrown\">https://github.com/chbrown</a>" }, { "name": "twitter", "value": "https://twitter.com/chbrown", "title": "Twitter", "show": "<a rel=\"me\" href=\"https://twitter.com/https://twitter.com/chbrown\">@https://twitter.com/chbrown</a>" }, { "name": "appdotnet", "value": "", "title": "App.net", "show": "" }, { "name": "homepage", "value": "http://henrian.com/", "title": "Homepage", "show": "<a rel=\"me\" href=\"http://henrian.com/\">http://henrian.com/</a>" }, { "name": "freenode", "value": "", "title": "IRC Handle", "show": "" } ], "avatarMedium": "https://secure.gravatar.com/avatar/56255b31d278b0c193f0f299ab01561b?s=100&d=retro", "name": "chbrown", "type": "user", "github": "chbrown", "homepage": "http://henrian.com/", "email": "io@henrian.com", "twitter": "chbrown", "date": "2013-05-06T04:33:50.569Z", "avatar": "https://secure.gravatar.com/avatar/56255b31d278b0c193f0f299ab01561b?s=50&d=retro", "freenode": "", "avatarLarge": "https://secure.gravatar.com/avatar/56255b31d278b0c193f0f299ab01561b?s=496&d=retro", "appdotnet": "", "roles": [] }

http://registry.npmjs.org/amulet

{ "_attachments": {}, "_id": "amulet", "_rev": "46-8ea15f9850c9574de038d4f9cb0908b8", "author": { "email": "io@henrian.com", "name": "Christopher Brown", "url": "http://henrian.com" }, "description": "As-soon-as-possible streaming async mustache templating", "dist-tags": { "latest": "1.0.7" }, "maintainers": [ { "email": "io@henrian.com", "name": "chbrown" } ], "name": "amulet", "readme": "# Amulet - Mustache templating for Node.js\n\nMustache is a ... ## License\n\nCopyright © 2011–2013 Christopher Brown. [MIT Licensed](LICENSE).\n", "repository": { "type": "git", "url": "git://github.com/chbrown/amulet.git" }, "time": { "0.1.5": "2011-08-24T20:49:39.725Z", ... "1.0.7": "2014-01-14T03:24:23.969Z", "created": "2011-08-24T20:49:38.532Z", "modified": "2014-01-14T03:24:23.968Z" }, "versions": { ... "1.0.7": { "_from": ".", "_id": "amulet@1.0.7", "_npmUser": { "email": "io@henrian.com", "name": "chbrown" }, "_npmVersion": "1.3.21", "author": { "email": "io@henrian.com", "name": "Christopher Brown", "url": "http://henrian.com" }, "bugs": { "email": "Christopher Brown ", "url": "https://github.com/chbrown/amulet/issues" }, "description": "As-soon-as-possible streaming async mustache templating", "devDependencies": { "portfinder": "*", "request": "*", "tap": "*" }, "directories": {}, "dist": { "shasum": "34f77074a0517fb21876f58bdf447c4e8cc3c56c", "tarball": "http://registry.npmjs.org/amulet/-/amulet-1.0.7.tgz" }, "homepage": "https://github.com/chbrown/amulet", "keywords": [ "template", "mustache", "mu", "asynchronous", "streaming", "nodeps" ], "license": "MIT", "maintainers": [ { "email": "io@henrian.com", "name": "chbrown" } ], "name": "amulet", "readme": "# Amulet - Mustache templating for Node.js\n\nMustache is a simple, ... Christopher Brown. [MIT Licensed](LICENSE).\n", "readmeFilename": "README.md", "repository": { "type": "git", "url": "git://github.com/chbrown/amulet.git" }, "scripts": { "test": "tap test" }, "version": "1.0.7" } } }

You can also use a semver specifier in the version position. The following all return the same payload.

http://registry.npmjs.org/amulet/*

http://registry.npmjs.org/amulet/~1.0

http://registry.npmjs.org/amulet/1.0.7

{ "_from": ".", "_id": "amulet@1.0.7", "_npmUser": { "email": "io@henrian.com", "name": "chbrown" }, "_npmVersion": "1.3.21", "author": { "email": "io@henrian.com", "name": "Christopher Brown", "url": "http://henrian.com" }, "bugs": { "email": "Christopher Brown <io@henrian.com>", "url": "https://github.com/chbrown/amulet/issues" }, "description": "As-soon-as-possible streaming async mustache templating", "devDependencies": { "portfinder": "*", "request": "*", "tap": "*" }, "directories": {}, "dist": { "shasum": "34f77074a0517fb21876f58bdf447c4e8cc3c56c", "tarball": "http://registry.npmjs.org/amulet/-/amulet-1.0.7.tgz" }, "homepage": "https://github.com/chbrown/amulet", "keywords": [ "template", "mustache", "mu", "asynchronous", "streaming", "nodeps" ], "license": "MIT", "maintainers": [ { "email": "io@henrian.com", "name": "chbrown" } ], "name": "amulet", "readme": "# Amulet - Mustache templating for Node.js\n\nMustache is a simple ... Christopher Brown. [MIT Licensed](LICENSE).\n", "readmeFilename": "README.md", "repository": { "type": "git", "url": "git://github.com/chbrown/amulet.git" }, "scripts": { "test": "tap test" }, "version": "1.0.7" }

api.npmjs.org

Download counts are relegated to a separate API, at the domain api.npmjs.org. The documentation at GitHub: npm/download-counts is almost comprehensive. The api.npmjs.org URLs point to a Joyent Manta server, proxied through a Fastly CDN, and the SSL is broken. All insecure http: requests are redirected to https:, so the easiest solution is not to verify the SSL certificate.

The point urls return flat JSON responses.

https://api.npmjs.org/downloads/point/last-month/flickr-with-uploads

{ "downloads": 113, "start": "2014-11-08", "end": "2014-12-07", "package": "flickr-with-uploads" }

https://api.npmjs.org/downloads/point/last-week/amulet

{ "downloads": 44, "start": "2014-12-01", "end": "2014-12-07", "package": "amulet" }

https://api.npmjs.org/downloads/point/last-week/amulet

{ "downloads": 44, "start": "2014-12-01", "end": "2014-12-07", "package": "amulet" }

https://api.npmjs.org/downloads/point/last-day/request

{ "downloads": 87463, "start": "2014-12-07", "end": "2014-12-07", "package": "request" }

You can also ask for a range, which returns much the same thing, only unsummed. If a day has 0 downloads, it will be missing from the result.

https://api.npmjs.org/downloads/range/last-week/http-enhanced

{ "downloads": [ {"day": "2014-12-02", "downloads": 10 }, {"day": "2014-12-03", "downloads": 71 }, {"day": "2014-12-04", "downloads": 1 }, {"day": "2014-12-06", "downloads": 1 } ], "start": "2014-12-01", "end": "2014-12-07", "package": "http-enhanced" }

You can call both point/range download requests with no package name to get overall counts.

https://api.npmjs.org/downloads/range/last-month

{ "downloads": [ {"day": "2014-11-08", "downloads": 10541316 }, {"day": "2014-11-09", "downloads": 9654281 }, {"day": "2014-11-10", "downloads": 24328909 }, {"day": "2014-11-11", "downloads": 25790529 }, {"day": "2014-11-12", "downloads": 26228722 }, {"day": "2014-11-13", "downloads": 26855130 }, {"day": "2014-11-14", "downloads": 25754384 }, {"day": "2014-11-15", "downloads": 12493827 }, {"day": "2014-11-16", "downloads": 11042083 }, {"day": "2014-11-17", "downloads": 26490237 }, {"day": "2014-11-18", "downloads": 28054740 }, {"day": "2014-11-19", "downloads": 28359947 }, {"day": "2014-11-20", "downloads": 28174239 }, {"day": "2014-11-21", "downloads": 25498948 }, {"day": "2014-11-22", "downloads": 12266345 }, {"day": "2014-11-23", "downloads": 10903174 }, {"day": "2014-11-24", "downloads": 25178567 }, {"day": "2014-11-25", "downloads": 28837632 }, {"day": "2014-11-26", "downloads": 26392288 }, {"day": "2014-11-27", "downloads": 20609579 }, {"day": "2014-11-28", "downloads": 18262603 }, {"day": "2014-11-29", "downloads": 9776744 }, {"day": "2014-11-30", "downloads": 10335674 }, {"day": "2014-12-01", "downloads": 25455841 }, {"day": "2014-12-02", "downloads": 20497259 }, {"day": "2014-12-03", "downloads": 27602909 }, {"day": "2014-12-04", "downloads": 20523249 }, {"day": "2014-12-05", "downloads": 26726277 }, {"day": "2014-12-06", "downloads": 11870278 }, {"day": "2014-12-07", "downloads": 10988879 } ], "start": "2014-11-08", "end": "2014-12-07" }

Requesting stats for a missing package will return an HTTP 200 OK, but the response payload will signify an error in different ways for points vs. ranges.

https://api.npmjs.org/downloads/range/last-month/pwjkqolamezt

{ "error": "no stats for this package for this range (0008)" }

https://api.npmjs.org/downloads/point/last-month/pwjkqolamezt

{ "downloads": null, "start": "2014-11-08", "end": "2014-12-07", "package": null }