How to use DEV.to API (2025)
3 min read

Dev.to’s API supports both unauthenticated and authenticated access, letting you fetch public articles or access private drafts, analytics, and more—all easily integrated into your Next.js portfolio.
🔓 1. Public Endpoints (No API Key Required)
Fetch any user's public posts with a simple GET request:
const articles = await fetch(`https://dev.to/api/articles?username=${username}`)
.then(res => res.json());
console.log(articles);
Example Response: https://dev.to/api/articles?username=dariomannu&page=1&per_page=5
[
{
"type_of": "article",
"id": 2691219,
"title": "Callforwards are actually not that bad!",
"description": "Have you ever tried callforwards? If you've used Express.js before, it's the same concept, but for...",
"readable_publish_date": "Jul 19",
"slug": "callforwards-are-actually-not-that-bad-475e",
"path": "/dariomannu/callforwards-are-actually-not-that-bad-475e",
"url": "https://dev.to/dariomannu/callforwards-are-actually-not-that-bad-475e",
"comments_count": 0,
"public_reactions_count": 4,
"collection_id": null,
"published_timestamp": "2025-07-19T09:00:00Z",
"language": "en",
"subforem_id": 1,
"positive_reactions_count": 4,
"cover_image": "https://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2h9k3bw7gtbtli24qtt3.png",
"social_image": "https://media2.dev.to/dynamic/image/width=1000,height=500,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2h9k3bw7gtbtli24qtt3.png",
"canonical_url": "https://dev.to/dariomannu/callforwards-are-actually-not-that-bad-475e",
"created_at": "2025-07-15T17:51:58Z",
"edited_at": "2025-07-19T07:25:14Z",
"crossposted_at": null,
"published_at": "2025-07-19T09:00:00Z",
"last_comment_at": "2025-07-19T09:00:00Z",
"reading_time_minutes": 2,
"tag_list": [
"javascript",
"frontend",
"webdev",
"express"
],
"tags": "javascript, frontend, webdev, express",
"user": {
"name": "Dario Mannu",
"username": "dariomannu",
"twitter_username": null,
"github_username": "dariomannu",
"user_id": 1100953,
"website_url": "https://github.com/reactivehtml",
"profile_image": "https://media2.dev.to/dynamic/image/width=640,height=640,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1100953%2F8136174b-bd57-4769-8a35-28a970127779.png",
"profile_image_90": "https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1100953%2F8136174b-bd57-4769-8a35-28a970127779.png"
}
},
]
You can:
-
Get by ID:
const article = await fetch(`https://dev.to/api/articles/${articleId}`) .then(res => res.json()); -
Get by slug:
const article = await fetch(`https://dev.to/api/articles/${username}/${slug}`) .then(res => res.json()); -
Get user info:
const user = await fetch(`https://dev.to/api/users/${userId}`) .then(res => res.json()); const userByName = await fetch(`https://dev.to/api/users/by_username?url=${username}`) .then(res => res.json());
🔐 2. Authenticated Endpoints (API Key Required)
Enable access to private drafts, analytics, followers, and more. Use only in server-side or API route — CORS disabled.
// Example server-side fetch
const articles = await fetch('https://dev.to/api/articles/me', {
headers: { 'api-key': process.env.DEV_TO_API_KEY }
}).then(res => res.json());
Available endpoints:
GET /api/articles/me– All your articles (drafts + published)GET /api/articles/me/publishedGET /api/articles/me/unpublishedGET /api/articles/me/allGET /api/users/me(your profile data)
🗂️ Feature Comparison Table
| Feature | Public (No Key) | Authenticated (With Key) |
|---|---|---|
| Authentication | ❌ None | ✅ api-key header |
| Access Scope | Public posts only | Your drafts, analytics, followers, etc. |
| Browser-Friendly | ✅ Yes | ❌ No—server/API routes only |
| CORS Support | ✅ Yes | ❌ No |
| Endpoints | /articles, /articles/:id, etc. | /me, /me/published, /me/unpublished, etc. |
🔧 How to Use in Next.js
a. Fetch Public Posts (SSG/ISR)
// app/page.tsx (Next.js)
export default async function HomePage() {
const posts = await fetch(
'https://dev.to/api/articles?username=yourname&per_page=5'
).then(res => res.json());
return (
<main>
<h1>Public Posts</h1>
<ul>
{posts.map(p => (
<li key={p.id}>
<a href={p.url} target="_blank" rel="noreferrer">
{p.title}
</a>
</li>
))}
</ul>
</main>
);
}
b. Fetch Private Data (API Route)
// app/api/devto.ts
import { NextResponse } from 'next/server';
export async function GET() {
const res = await fetch('https://dev.to/api/articles/me', {
headers: { 'api-key': process.env.DEV_TO_API_KEY! }
});
const data = await res.json();
return NextResponse.json(data);
}
Usage in React frontend:
useEffect(() => {
fetch('/api/devto')
.then(res => res.json())
.then(setMyArticles)
.catch(console.error);
}, []);
💡 Pro Tips
- Use
per_page+pageparams for pagination control. - Leverage article IDs to fetch full content or stats.
- Combine public & private data for dynamic, rich blog sections in your portfolio.
✅ Final Takeaway
- No API key? Great—fetch public posts directly on the client or server.
- Got a key? Unlock private drafts, metrics, and a complete dashboard—securely, server-side.
- Seamlessly integrate both modes in your Next.js site and showcase a holistic Dev.to-powered blog!
- Visit officials docs Forem