This endpoint updates the user’s resume data and publication status. It’s used to publish a completed resume to make it viewable at the user’s public profile URL, or to unpublish by passing null.
Endpoint
POST /api/user/publish-resume
Request
The complete resume object to publish, or null to unpublish the resume.When publishing, this should be a complete Resume object with all sections. When unpublishing, pass null to remove the public resume and set islive to false.
Resume structure
The resume object should follow this structure:
- personalInfo: Object containing name, title, location, contact details, and social links
- summary: String with professional summary
- skills: Object with arrays for languages, frameworksAndTools, and softSkills
- experience: Array of work experience objects
- projects: Array of project objects
- education: Array of education objects
- extracurricular: Array of strings
- customSections: Array of custom section objects
See the Extract info endpoint documentation for the complete schema.
Response
Returns the updated user object:
User’s Clerk authentication ID
The published resume object, or null if unpublished
Publication status. Set to true when a resume is published, false when unpublished.
Account creation timestamp
Examples
Publish a resume
curl -X POST https://wrkks.vercel.app/api/user/publish-resume \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"resume": {
"personalInfo": {
"name": "John Doe",
"title": "Software Engineer",
"email": "[email protected]",
"location": "San Francisco, CA",
"phone": "+1 (555) 123-4567",
"website": "https://johndoe.com",
"linkedin": "https://linkedin.com/in/johndoe",
"github": "https://github.com/johndoe",
"twitter": "",
"imageUrl": ""
},
"summary": "Experienced software engineer...",
"skills": {
"languages": ["JavaScript", "TypeScript"],
"frameworksAndTools": ["React", "Next.js"],
"softSkills": ["Leadership"]
},
"experience": [],
"projects": [],
"education": [],
"extracurricular": [],
"customSections": []
}
}'
Response
{
"id": "usr_123",
"clerk_user_id": "user_abc",
"email": "[email protected]",
"username": "johndoe",
"resume": {
"personalInfo": { /* ... */ },
"summary": "Experienced software engineer...",
"skills": { /* ... */ },
"experience": [],
"projects": [],
"education": [],
"extracurricular": [],
"customSections": []
},
"islive": true,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-02-28T14:25:00Z"
}
Unpublish a resume
curl -X POST https://wrkks.vercel.app/api/user/publish-resume \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"resume": null
}'
Response
{
"id": "usr_123",
"clerk_user_id": "user_abc",
"email": "[email protected]",
"username": "johndoe",
"resume": null,
"islive": false,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-02-28T14:30:00Z"
}
Error responses
401 Unauthorized
Returned when the user is not authenticated:
{
"msg": "User not authenticated"
}
500 Internal Server Error
Returned when the database update fails:
{
"msg": "Failed to publish resume"
}
Or for unexpected errors:
{
"msg": "Internal server error"
}
Implementation
The endpoint automatically manages the islive status based on the resume value:
const { data, error } = await supabase
.from("users")
.update({
resume,
islive: resume === null ? false : true,
updated_at: new Date().toISOString(),
})
.eq("clerk_user_id", userId)
.select()
.single();
When resume is null, islive is set to false. Otherwise, it’s set to true.
Source: /app/api/user/publish-resume/route.ts:22-31