Open Source Projects — entry 004 of 8
Drupal.org
Drupal.org exposes its community project and node data through a legacy Drupal 7 REST endpoint (`drupal.org/api-d7/node.json`); a live unauthenticated GET returned a 200 JSON body with `Access-Control-Allow-Origin: *`, resolving cors "unknown" to "yes". It's a free community resource run by the nonprofit Drupal Association, with no authentication or paid tier for reading published project data.
Drupal.org exposes its own project/issue/user data through a legacy Drupal 7 REST endpoint. A live GET to /node.json?limit=1 returned a 200 JSON body with self/first/last/next pagination links plus a list array of full node objects, and access-control-allow-origin: * with access-control-allow-methods: GET, OPTIONS confirmed keyless cross-origin access — both reconfirmed by this run's own probe.
GreatAPIs Score
Auth quickstart
- No API key or signup required to read published node data — every probe in this file returned real records with no auth header sent at all.
Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.
List the oldest surviving node
GEThttps://www.drupal.org/api-d7/node.json?limit=1
{"self":"https:\/\/www.drupal.org\/api-d7\/node?limit=1","first":"https:\/\/www.drupal.org\/api-d7\/node?limit=1\u0026page=0","last":"https:\/\/www.drupal.org\/api-d7\/node?limit=1\u0026page=2203092","next":"https:\/\/www.drupal.org\/api-d7\/node?limit=1\u0026page=1","list":[{"body":{"value":"\u003Cp\u003Ethe \u0022teaser\u0022 \/ \u0022read more\u0022 handling doesnt work properly - the index page shows \/complete\/ articles, not just teasers and the \u0022read more\u0022 link.\u003C\/p\u003E\n\u003Cp\u003Ereason: function node($node, $main = 0) in sunflower.theme is missing something like\u003C\/p\u003E\n\u003Cpre class=\u0022codeblock\u0022\u003E\u003Ccode class=\u0022language-php\u0022\u003Eif ($main \u0026amp;\u0026amp; $node-\u0026gt;teaser) {\n echo check_output($node-\u0026gt;teaser, 1);\n}\nelse {\n echo check_output($node-\u0026gt;body, 1); \n}\n\n\u003C\/code\u003E\u003C\/pre\u003E\u003Cp\u003E(this is from unconed.theme)\u003C\/p\u003E","summary":"","format":"1"},"taxonomy_vocabulary_9":[],"field_issue_status":"7","field_issue_priority":"200","field_issue_category":"1","field_issue_component":"Code","field_issue_assigned":{"uri":"https:\/\/www.drupal.org\/api-d7\/user\/2","id":"2","resource":"user"},"field_project":{"uri":"https:\/\/www.drupal.org\/api-d7\/node\/3060","id":"3060","resource":"node"},"field_issue_files":[],"field_issue_related":[],"field_issue_version":null,"field_issue_last_status_change":"1008695516","field_issue_parent_link":[],"field_issue_related_links":[],"flag_project_issue_follow_user":[{"uri":"https:\/\/www.drupal.org\/api-d7\/user\/2","id":2,"resource":"user"},{"uri":"https:\/\/www.drupal.org\/api-d7\/user\/8","id":8,"resource":"user"}],"nid":"15","vid":"2897929","is_new":false,"type":"project_issue","title":"sunflower.theme: incorrect \u0022teaser\u0022 \/ \u0022read more\u0022 handling","language":"und","url":"https:\/\/www.drupal.org\/project\/drupal\/issues\/15","edit_url":"https:\/\/www.drupal.org\/node\/15\/edit","status":"1","promote":"0","sticky":"0","created":"1008695516","changed":"1010515673","author":{"uri":"https:\/\/www.drupal.org\/api-d7\/user\/8","id":"8","resource":"user","name":"ax"},"comment":"2","comments":[{"uri":"https:\/\/www.drupal.org\/api-d7\/comment\/287095","id":287095,"resource":"comment"},{"uri":"https:\/\/www.drupal.org\/api-d7\/comment\/287096","id":287096,"resource":"comment"}],"comment_count":"2","comment_count_new":false,"feeds_item_guid":null,"feeds_item_url":null,"feed_nid":null,"flag_flag_tracker_follow_user":[],"flag_tracker_follower_count":"2","has_new_content":null,"last_comment_timestamp":"1741978025"}]}Captured byte-for-byte from this run's live probe, reconfirmed stable on a repeat call a second later (same node id 15 both times — the default listing sorts node id ascending, and 15 is one of the lowest surviving ids). The last/next page numbers (2203092/1) will drift upward over time as new nodes are created; the node object shape and the pagination envelope are what's stable. Note every URL and / inside the body is JSON-escaped as \/, and HTML entities inside the issue body text (\u003Cp\u003E, \u0026amp;) are Unicode-escaped rather than left as raw </& — real behavior of Drupal 7's JSON serializer, not a formatting artifact of this capture.
Developer reference
https://www.drupal.org/api-d7Gotchas & limits
- The pagination links the API itself returns aren't directly usable:
nextabove ishttps://www.drupal.org/api-d7/node?limit=1&page=1— note the missing.jsonsuffix. A live GET to that exact bare URL returnedHTTP 404withcontent-type: text/html; charset=utf-8(a rendered Drupal 404 page, not a JSON error) —.jsonmust be re-inserted before the URL the API gave you will actually work. - An unrecognized
typefilter doesn't error, it returns an empty result set: a live GET to/node.json?type=zzznotarealtype&limit=1returnedHTTP 200with body{"self":"https:\/\/www.drupal.org\/api-d7\/node?type=zzznotarealtype\u0026limit=1","first":"https:\/\/www.drupal.org\/api-d7\/node?type=zzznotarealtype\u0026limit=1\u0026page=0","last":"https:\/\/www.drupal.org\/api-d7\/node?type=zzznotarealtype\u0026limit=1\u0026page=0","list":[]}— the full pagination envelope is present even though nothing matched. - A nonexistent node id doesn't 404, it returns a near-empty stub object: a live GET to
/node/999999999.jsonreturnedHTTP 200with body{"comments":[],"body":[],"flag_flag_tracker_follow_user":[]}— three empty arrays and nothing else, not an error envelope and not the 404 a REST client would expect for a missing resource. - Every URL embedded in a response body comes back JSON-escaped: the
self/first/last/nextlinks and every nestedurifield above render slashes as\/(e.g.https:\/\/www.drupal.org\/api-d7\/node?limit=1) — valid JSON, but a client doing naive string matching against an un-escaped URL will miss.