The DEV API drops the "published" field on the endpoint you would check it from
If you script your posting to dev.to, the obvious way to confirm a post went live is to read published back from the API. On the endpoint you would naturally use for that, the field is not false and it is not null. It is not in the response at all, so article.get("published") hands you None and your script decides a live article is still a draft.
The reliable check is simpler: use an unauthenticated GET /api/articles/{id} returning HTTP 200 as proof that a stranger can read the article. Use the author-scoped collections when you need to distinguish drafts from published posts.
Everything below was measured on 2026-08-21 against dev.to with API v1, on my own account, with three published articles and one draft.
One article, two shapes
The author-scoped list endpoint carries the field:
curl -s "https://dev.to/api/articles/me/published?per_page=1" \
-H "api-key: $DEVTO_KEY" \
-H "accept: application/vnd.forem.api-v1+json" \
| python3 -c 'import sys,json;a=json.load(sys.stdin)[0];print(a["id"], a["published"], a["published_at"])'
4408696 True 2026-08-16T07:13:13.534Z
The single-article endpoint, same key, same article id, does not:
curl -s "https://dev.to/api/articles/4408696" \
-H "api-key: $DEVTO_KEY" \
-H "accept: application/vnd.forem.api-v1+json" \
| python3 -c 'import sys,json;a=json.load(sys.stdin);print("published" in a, a.get("published_at"))'
False 2026-08-16T07:13:13Z
I ran that request three ways, with the api-key header, without it, and without the vendor accept header, and "published" in a was False every time. So this is not a permissions difference between an author and a stranger. The key does not change it.
The write path is the same shape. A PUT /api/articles/{id} returned HTTP 200 and a body with no published key either, even though published is a field I had just sent in the request.
Which leaves the two ways a script gets this wrong:
article["published"]raisesKeyErroron a successful publish.article.get("published")quietly reports a public article as unpublished, which is worse, because that branch usually retries.
Why published is an input
You send it on POST /api/articles and on PUT /api/articles/{id} to move a draft to public. The collections under /api/articles/me/* are author-scoped, so they describe your article the way its owner sees it and echo the flag back.
GET /api/articles/{id} is a different representation. It serves the article the way an anonymous reader receives it, and in that view there is no publication state to report, because an article you can fetch there is by definition one that is published.
The negative control
That last sentence is the part worth testing rather than assuming, so I asked the endpoint for something the public cannot see. I created a draft with "published": false, took its id from GET /api/articles/me/unpublished, and requested it directly.
curl -s -o /dev/null -w "%{http_code}\n" "https://dev.to/api/articles/4449977"
404
Then the same request with my own key, for my own draft:
curl -s -w " HTTP %{http_code}\n" "https://dev.to/api/articles/4449977" \
-H "api-key: $DEVTO_KEY" \
-H "accept: application/vnd.forem.api-v1+json"
{"error":"not found","status":404} HTTP 404
My
Comments
No comments yet. Start the discussion.