Desarrolladores

La API de StackPortfolio permite que tus propios scripts y herramientas lean y actualicen tu perfil y tus proyectos. Es una API JSON que funciona a través de HTTPS y está documentada con un documento OpenAPI 3.1.

Developer Platform Overview

Stackportfolio provides a unified developer platform accessible via standard REST endpoints and the Model Context Protocol (MCP). Authenticate requests using Personal API keys with Bearer authorization.

URL base: https://stackportfol.io/api/v1

Obtén una clave de API

Crea una clave en tu página de claves de API. Asigna solo los permisos que la herramienta necesita y una fecha de caducidad entre 30 y 365 días. La clave se muestra solo una vez, así que guárdala en un lugar seguro; puedes revocarla en cualquier momento.

Autentícate

Envía la clave con cada solicitud, en cualquiera de estos encabezados. Las cookies nunca se utilizan. Una clave que falta, es incorrecta, ha expirado o ha sido revocada siempre devolverá el mismo error 401.

Alcances

Cada operación requiere un alcance específico, que se muestra en la referencia a continuación. Si una clave no tiene el alcance necesario, se mostrará un error 403 con el código "insufficient_scope". La solicitud GET /me funciona con cualquier clave válida y muestra los alcances asociados a esa clave.

  • profile:read Lee tu perfil
  • profile:write Actualiza tu perfil
  • projects:read Lee tus proyectos
  • projects:write Crea y actualiza tus proyectos
  • projects:delete Elimina tus proyectos (acción irreversible)

Protocolo de Contexto de Modelo (MCP)

StackPortfolio también es un servidor MCP. Dirige un cliente MCP como Claude a la siguiente dirección: este se registrará, te pedirá que inicies sesión y apruebes los permisos que necesita, y luego realizará las mismas operaciones que la API, con tus permisos. No se necesita ninguna clave de API.

Servidor MCP: https://stackportfol.io/mcp

Web MCP Browser Integration

Stackportfolio exposes client-side Web MCP discovery via navigator.modelContext. Browser-based AI agents can discover tools natively in the user's active session without passing manual credentials.

Projects API

List, create, and manage projects. Pass scope=mine to retrieve projects you own or maintain, or scope=visible to browse public projects.

Contribution Stories API

Publish structured "How I worked on this" stories detailing problems, engineering approaches, corrections, and practices.

Límites de uso

Cada cuenta puede realizar 3 solicitudes por segundo, 30 por minuto, 300 por hora y 1,000 por día, contando todas sus claves. Si se supera cualquiera de estos límites, las solicitudes recibirán un código de error 429 con el código "rate_limited" y un encabezado "Retry-After" que indica los segundos que debes esperar. Cada respuesta incluye los campos "RateLimit-Limit", "RateLimit-Remaining" y "RateLimit-Reset".

Errores

Cada error tiene la misma estructura JSON. El código es estable y es seguro crear una rama a partir de él; el mensaje está escrito para las personas y puede cambiar.

unauthorized HTTP 401
La clave está ausente, es incorrecta, es desconocida, ha expirado o ha sido revocada.
insufficient_scope HTTP 403
La clave no tiene el alcance que la operación requiere.
not_found HTTP 404
No existe ese recurso, o no es uno que puedas ver o modificar.
validation_failed HTTP 400
La solicitud no es válida. La sección "detalles" enumera cada problema junto con la ruta del campo correspondiente.
conflict HTTP 409
Este cambio entra en conflicto con el estado actual, por ejemplo, al agregar una tecnología dos veces.
rate_limited HTTP 429
La clave ha agotado su límite de uso por hora.
internal HTTP 500
Algo salió mal en nuestro sistema. Intentarlo de nuevo más tarde es seguro para las operaciones de lectura.

Referencia de la API

Generado a partir de los mismos esquemas que utiliza el servidor para validar las solicitudes. La referencia está en inglés.

Descargar openapi.json
GET /openapi.json

This document

Alcance: No se necesita ninguna clave

Devuelve: 200 — The OpenAPI 3.1 document. object
GET /docs/search

Search developer documentation

Search documentation sections, guides, REST API endpoints, schemas, and MCP tools.

Alcance: profile:read

Parámetros

?query string
Search query to look up in documentation.
?limit integer
Maximum number of results to return.; min 1; max 50; default 10
Devuelve: 200 — Matching documentation sections. object
GET /me

The key owner and its scopes

Alcance: cualquier clave válida

Devuelve: 200 — Who the key belongs to. Me
GET /profile

The caller's tech profile

Alcance: profile:read

Devuelve: 200 — The profile. Profile
PATCH /profile

Update the caller's tech profile

A partial update merged onto the stored profile; null clears a field. A GET body can be sent back as is.

Alcance: profile:write

Cuerpo de la solicitud

title string
min length 1; max length 100
experienceLevel "junior" | "mid" | "senior" | "lead"
githubUsername string
max length 39
gitlabUsername string
max length 39
bitbucketUsername string
max length 39
seekingEmployment boolean
openToOpportunities boolean
preferredSalaryMin integer
min 0; max 100000000
preferredSalaryMax integer
min 0; max 100000000
salaryCurrency "USD" | "EUR" | "GBP" | "CAD"
availableDate string
yyyy-mm-dd, or a full ISO date-time.
Devuelve: 200 — The updated profile. Profile
GET /projects

List projects

mine is every project the caller is on, private ones and open invitations included; visible is every project they may read.

Alcance: projects:read

Parámetros

?scope "mine" | "visible"
Which projects to list.; default "mine"
?limit integer
Page size, clamped to 1–100.; min 1; max 100; default 20
?offset integer
Rows to skip.; min 0; default 0
Devuelve: 200 — A page of projects. { data: ProjectSummary[]; pagination: Pagination }
POST /projects

Create a project

The caller becomes its OWNER. Visibility defaults to private. Listed technologies are credited to the caller. Past the active-project limit the project is still created, with deactivatedAt set. Project creation has its own hourly and daily limit (429).

Alcance: projects:write

Cuerpo de la solicitud

name string obligatorio
min length 1; max length 200
description string
max length 5000; default ""
repositoryUrl string
max length 500; default ""
deployedUrl string
max length 500; default ""
organisation string
max length 200; default ""
technologies (string | { name: string; version: string | null })[] | string
Credited to the caller. At most 50.
contributors (string | { name: string; version: string | null })[] | string
Usernames or emails of existing users, invited unaccepted.
visibility "public" | "unlisted" | "private"
default "private"
saveAsDraft boolean
default false
parentId string (uuid) | null
Create this project as a part of another.
Devuelve: 201 — The new project. Project
GET /projects/{id}

Get a project

Alcance: projects:read

Parámetros

{id} string obligatorio
Project id (uuid).
Devuelve: 200 — The project. Project
PATCH /projects/{id}

Update a project

A partial update; null clears a field. Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).

Cuerpo de la solicitud

name string
min length 1; max length 200
description string
max length 5000
repositoryUrl string
max length 500
deployedUrl string
max length 500
organisation string | { name: string }
technologies (string | { name: string; version: string | null })[] | string
The complete new list, at most 50. Omit it to keep the current technologies.
formerRows string[]
former string[]
replacedBy string[]
visibility "public" | "unlisted" | "private"
isArchived boolean
isActive boolean
The inverse of isArchived; either may be sent.
deactivated boolean
Owner only. false activates the project, which is a 409 when the owner is already at their active-project limit.
Devuelve: 200 — The updated project. Project
DELETE /projects/{id}

Delete a project

Irreversible. Its technologies, contributors, media and evidence go with it and every credited contributor is rescored; its parts are kept and become root projects. Needs the separate projects:delete scope, which projects:write does not imply. Only the accepted OWNER may delete; anyone else gets the same 404 as for a missing project.

Alcance: projects:delete

Parámetros

{id} string obligatorio
Project id (uuid).
Devuelve: 204 — Deleted.
GET /projects/{id}/technologies

List a project's technologies

Alcance: projects:read

Parámetros

{id} string obligatorio
Project id (uuid).
?limit integer
Page size, clamped to 1–100.; min 1; max 100; default 20
?offset integer
Rows to skip.; min 0; default 0
Devuelve: 200 — A page of technologies. { data: ProjectTechnology[]; pagination: Pagination }
POST /projects/{id}/technologies

Add a technology

Credits every accepted contributor with it. A project lists at most 50 technologies; one more is a 409. Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).

Cuerpo de la solicitud

name string obligatorio
min length 1; max length 100
version string | null
The major or major.minor version the project used, like "5" or "3.12"; null when unknown.
former boolean
Whether the project moved off this technology.
replacedBy string (uuid) | null
The id of the technology that replaced it, which the project must list and which must not be this one. Needs former: true; null clears it, as does former: false.
Devuelve: 201 — The attached technology. ProjectTechnology
GET /projects/{id}/media

List a project's media

Lists all media items for a project in gallery order.

Alcance: projects:read

Parámetros

{id} string obligatorio
Project id (uuid).
?limit integer
Page size, clamped to 1–100.; min 1; max 100; default 20
?offset integer
Rows to skip.; min 0; default 0
Devuelve: 200 — A page of media items. { data: ProjectMedia[]; pagination: Pagination }
POST /projects/{id}/media

Add an image to a project

Optimises the image server-side and appends it to the project's gallery; the first image becomes the cover. Takes a JSON body with base64 data, or multipart/form-data with a file part and an optional description. The decoded image may be at most 5 MB. A project holds a limited number of images set by its owner's plan; one more is a 409. Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).

Cuerpo de la solicitud

data string obligatorio
The image, base64-encoded (a data: URL is accepted). PNG, JPEG, WebP or a still GIF; at most 6 MB of base64 in a JSON body. It is resized to at most 2048px, converted to WebP and stripped of metadata. The REST endpoint also takes multipart/form-data with the file in a file field.; min length 1
description string
Caption and alt text for the image.; max length 200
Devuelve: 201 — The stored image. ProjectMedia
POST /projects/{id}/media/uploads

Create a single-use upload URL for a project image

Generates a short-lived (10 min), single-use HMAC-signed PUT URL to upload a project image directly without base64 encoding. Accepts PNG, JPEG, or WebP up to 5 MB. Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).

Cuerpo de la solicitud

filename string obligatorio
Original filename for the image, including extension.; min length 1
contentType "image/png" | "image/jpeg" | "image/webp" obligatorio
The MIME type of the image to upload (image/png, image/jpeg, or image/webp).
description string
Caption and alt text for the image.; max length 200
altText string
Alt text for the image (defaults to description if omitted).; max length 200
Devuelve: 201 — The signed upload URL and required headers. ProjectMediaUpload
PUT /uploads/{token}

Upload an image to a signed URL

Authorised by the signed URL alone, no key. The body is the raw PNG, JPEG or WebP bytes (not multipart) with the Content-Type from createProjectMediaUpload, at most 5 MB. The URL works once and expires after 10 minutes; a used URL is a 409, an expired one a 410, an oversized body a 413. Responds with the stored image.

Alcance: No se necesita ninguna clave

Parámetros

{token} string obligatorio
The signed token from the upload URL.
Devuelve: 201 — The stored image. ProjectMedia
PATCH /projects/{id}/media/{mediaId}

Update a project's media item

Updates metadata (caption, alt text), position/sort order, or cover status for a media item. Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).
{mediaId} string obligatorio
Media item id (uuid).

Cuerpo de la solicitud

caption string | null
Caption for the image; null clears it.
altText string | null
Alt text for the image; null clears it.
position integer
New 0-indexed position in the gallery.; min 0; max 9007199254740991
sortOrder integer
Alias for position.; min 0; max 9007199254740991
makeCover boolean
Whether this media item should become the project cover.
Devuelve: 200 — The updated media item. ProjectMedia
PUT /projects/{id}/media/{mediaId}

Replace a project's media image

Replaces the image file with a new upload (base64 data or multipart file). Optimises to WebP with responsive variants and deletes the old stored objects. Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).
{mediaId} string obligatorio
Media item id (uuid).

Cuerpo de la solicitud

data string obligatorio
The replacement image, base64-encoded. At most 6 MB of base64; data: URL accepted.; min length 1
description string
Optional caption and alt text for the replacement image.; max length 200
Devuelve: 200 — The updated media item. ProjectMedia
DELETE /projects/{id}/media/{mediaId}

Remove a project's media item

Deletes the media item and its stored files (including variants), repairing cover and position ordering. Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).
{mediaId} string obligatorio
Media item id (uuid).
Devuelve: 204 — The media item was removed.
PATCH /projects/{id}/technologies/{technologyId}

Update a technology on a project

Marks a technology former (moved off), optionally naming the technology that replaced it. Send only the keys to change. A former technology still counts for proficiency, so nobody is rescored. A technology the project does not list and a project the caller may not edit are the same 404. Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).
{technologyId} string obligatorio
Technology id (uuid).

Cuerpo de la solicitud

version string | null | string
The version to set; null or "" clears it.
former boolean
Whether the project moved off this technology.
replacedBy string (uuid) | null
The id of the technology that replaced it, which the project must list and which must not be this one. Needs former: true; null clears it, as does former: false.
Devuelve: 200 — The technology. ProjectTechnology
DELETE /projects/{id}/technologies/{technologyId}

Remove a technology

Deletes the evidence it gave on this project and rescores its contributors. Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).
{technologyId} string obligatorio
Technology id (uuid).
Devuelve: 204 — Removed.
GET /projects/{id}/contributors

List a project's contributors

Open invitations included. No email addresses.

Alcance: projects:read

Parámetros

{id} string obligatorio
Project id (uuid).
?limit integer
Page size, clamped to 1–100.; min 1; max 100; default 20
?offset integer
Rows to skip.; min 0; default 0
Devuelve: 200 — A page of contributors. { data: Contributor[]; pagination: Pagination }
POST /projects/{id}/contributors

Invite a contributor

Invites an existing user by username or email; they are notified and must accept. Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).

Cuerpo de la solicitud

identifier string obligatorio
min length 1; max length 254
role "MAINTAINER" | "CONTRIBUTOR"
default "CONTRIBUTOR"
Devuelve: 201 — The invitation. Contributor
PATCH /projects/{id}/contributors/{userId}

Change a contributor's role

The owner's role cannot be changed (409). Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).
{userId} string obligatorio
The contributor's user id.

Cuerpo de la solicitud

role "MAINTAINER" | "CONTRIBUTOR" obligatorio
Devuelve: 200 — The contributor. Contributor
DELETE /projects/{id}/contributors/{userId}

Remove a contributor

Also cancels an open invitation, deletes their evidence on this project and rescores them. Only an accepted OWNER or MAINTAINER may write; anyone else gets the same 404 as for a missing project.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).
{userId} string obligatorio
The contributor's user id.
Devuelve: 204 — Removed.
PUT /projects/{id}/contributors/{userId}/technologies

Set which technologies a contributor used

Replaces one accepted contributor's technology credits on this project and rescores them; proficiency stays computed. The caller may set their own, and an accepted OWNER or MAINTAINER anyone's but the owner's. A pending invitee, a target the caller may not change, and a project the caller is not on are the same 404.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).
{userId} string obligatorio
The contributor's user id.

Cuerpo de la solicitud

technologyIds (string (uuid))[] obligatorio
The whole set, replacing the current one. Each must be one of the project's technologies.
Devuelve: 200 — The contributor. Contributor
PUT /projects/{id}/contributors/{userId}/skills

Set the skills a contributor used

Replaces the caller's own skills on this project and recomputes their skill levels. userId must be the caller: nobody records skills for someone else, and any other id is a 404.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).
{userId} string obligatorio
The contributor's user id.

Cuerpo de la solicitud

skills string[] obligatorio
The whole list, replacing the current one. At most 10, each at most 50 characters; repeats are dropped case-insensitively.
Devuelve: 200 — The contributor. Contributor
GET /stories

List contribution stories

Every "How I worked on this" account on the projects the caller may see, newest project activity first. mine keeps only the caller’s own stories.

Alcance: projects:read

Parámetros

?scope "all" | "mine"
Which stories to list.; default "all"
?limit integer
Page size, clamped to 1–100.; min 1; max 100; default 20
?offset integer
Rows to skip.; min 0; default 0
Devuelve: 200 — A page of stories. { data: Story[]; pagination: Pagination }
GET /projects/{id}/stories

List a project's contribution stories

Every "How I worked on this" account written on the project, as its page renders them. mine keeps only the caller’s own.

Alcance: projects:read

Parámetros

{id} string obligatorio
Project id (uuid).
?scope "all" | "mine"
Which stories to list.; default "all"
?limit integer
Page size, clamped to 1–100.; min 1; max 100; default 20
?offset integer
Rows to skip.; min 0; default 0
Devuelve: 200 — A page of stories. { data: Story[]; pagination: Pagination }
GET /projects/{id}/stories/{userId}

Get one contributor's story

One contributor's story on a project the caller may see. Any author's story is readable, as the project page renders it; pass the caller's own id from /me to read theirs.

Alcance: projects:read

Parámetros

{id} string obligatorio
Project id (uuid).
{userId} string obligatorio
The contributor's user id.
Devuelve: 200 — The story. Story
PUT /projects/{id}/story

Write the caller's story

Writes the caller’s own "How I worked on this" account, replacing any previous one. Every accepted contributor may write theirs, and nobody — owner included — may write anybody else’s: a project the caller is not on and a missing one are the same 404. Declaring a practice makes corrections mandatory, which is the anti-AI-washing rule the web editor enforces.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).

Cuerpo de la solicitud

problem string obligatorio
min length 40; max length 600
approach string obligatorio
min length 40; max length 800
corrections string
max length 800; default ""
hindsight string
max length 400; default ""
practices ({ tool: string; role: "EXPLORED_OPTIONS" | "WROTE_FIRST_DRAFT" | "REVIEWED_MY_WORK" | "DID_REPETITIVE_PART" | "BUILT_END_TO_END" | "SOMETHING_ELSE"; askedFor: string })[]
default []
links ({ label: string; url: string })[]
default []
Devuelve: 200 — The saved story. Story
DELETE /projects/{id}/story

Delete the caller's story

Deletes the caller’s own story on the project. The contribution itself is untouched: only the write-up goes. Only ever the caller’s own story, so projects:write is enough.

Alcance: projects:write

Parámetros

{id} string obligatorio
Project id (uuid).
Devuelve: 204 — Deleted.

Esquemas

Error

error { code: "unauthorized" | "insufficient_scope" | "not_found" | "validation_failed" | "conflict" | "rate_limited" | "internal"; message: string; details: any } obligatorio

Pagination

limit integer obligatorio
min -9007199254740991; max 9007199254740991
offset integer obligatorio
min -9007199254740991; max 9007199254740991
total integer obligatorio
min -9007199254740991; max 9007199254740991

Me

userId string obligatorio
username string,null obligatorio
scopes ("profile:read" | "profile:write" | "projects:read" | "projects:write" | "projects:delete")[] obligatorio
via "api_key" | "oauth" obligatorio

Profile

userId string obligatorio
title string,null obligatorio
experienceLevel string,null obligatorio
githubUsername string,null obligatorio
gitlabUsername string,null obligatorio
bitbucketUsername string,null obligatorio
seekingEmployment boolean obligatorio
openToOpportunities boolean obligatorio
preferredSalaryMin number,null obligatorio
preferredSalaryMax number,null obligatorio
salaryCurrency "USD" | "EUR" | "GBP" | "CAD" | null obligatorio
availableDate string (date-time) | null obligatorio
createdAt string (date-time) obligatorio
updatedAt string (date-time) obligatorio
areas ({ slug: string; name: string; group: "languages" | "frontend" | "backend" | "data" | "infrastructure" | "developer-tooling" | "quality" | "mobile" | "ai" | "other"; projectCount: number; level: number; technologies: ({ id: string; name: string })[] })[] obligatorio
The categories your project credits fall into (one per technology), most projects first. Computed, read-only.
indicator { label: "specialist" | "generalist" | null; breadth: number; depth: number; topArea: { slug: "languages" | "frontend" | "backend" | "data" | "infrastructure" | "developer-tooling" | "quality" | "mobile" | "ai" | "other"; name: string }; projectCount: number } | null obligatorio
null with no areas, or when you have hidden it in settings. Computed, read-only.

ProjectSummary

id string (uuid) obligatorio
name string obligatorio
description string,null obligatorio
repositoryUrl string,null obligatorio
provider "github" | "gitlab" | "bitbucket" | null obligatorio
image string,null obligatorio
images string[] obligatorio
Card images, cover first.
isActive boolean obligatorio
isPublic boolean obligatorio
starCount integer obligatorio
min -9007199254740991; max 9007199254740991
lastActivityDate string (date-time) obligatorio
createdAt string (date-time) obligatorio
role "OWNER" | "MAINTAINER" | "CONTRIBUTOR" | null obligatorio
The caller's role on the project, if any.
accepted boolean,null obligatorio
Whether the caller has accepted their invitation.
pinnedPosition integer | null obligatorio
Where the caller pinned the project on their profile (1 is first), or null. Only scope=mine sets it, and that list is already ordered pins first.

Project

id string (uuid) obligatorio
name string obligatorio
description string,null obligatorio
repositoryUrl string,null obligatorio
deployedUrl string,null obligatorio
provider string,null obligatorio
image string,null obligatorio
isActive boolean obligatorio
isPublic boolean obligatorio
deactivatedAt string (date-time) | null obligatorio
Set while the project is outside its owner's active-project limit. An inactive project is private to everyone but its contributors.
visibility "public" | "unlisted" | "private" obligatorio
effectiveVisibility "public" | "unlisted" | "private" obligatorio
The visibility once every ancestor is taken into account.
starCount integer obligatorio
min -9007199254740991; max 9007199254740991
commitCount integer obligatorio
min -9007199254740991; max 9007199254740991
viewCount integer obligatorio
min -9007199254740991; max 9007199254740991
lastActivityDate string (date-time) obligatorio
createdAt string (date-time) obligatorio
viewerRole "OWNER" | "MAINTAINER" | "CONTRIBUTOR" | null obligatorio
The caller's accepted role, if any.
organisation { id: string (uuid); name: string; slug: string; isApproved: boolean; isVerified: boolean; logoUrl: string,null } | null obligatorio
This project's organisation, or its nearest ancestor's.
ancestors ({ id: string (uuid); name: string })[] obligatorio
The parent chain, root first, names only.
technologies ({ id: string (uuid); name: string; version: string | null; isApproved: boolean; former: boolean; replacedBy: { id: string (uuid); name: string } | null; categories: ({ slug: string; name: string })[] })[] obligatorio
media ({ id: string (uuid); kind: "image" | "video_embed"; url: string; posterUrl: string,null; embedProvider: "youtube" | "vimeo" | "loom" | null; embedId: string,null; caption: string,null; altText: string,null; position: integer; isCover: boolean })[] obligatorio

Technology

id string (uuid) obligatorio
name string obligatorio

ProjectTechnology

id string (uuid) obligatorio
name string obligatorio
version string | null obligatorio
The major or major.minor version the project used, like "5" or "3.12"; null when unknown.
isApproved boolean obligatorio
False while awaiting admin approval; visible to project members.
former boolean obligatorio
The project moved off it. It still counts as evidence for proficiency.
replacedBy { id: string (uuid); name: string } | null obligatorio
What replaced it: another technology on this project. Only set when former.
categories ({ slug: string; name: string })[] obligatorio

ProjectMedia

id string (uuid) obligatorio
kind "image" | "video_embed" obligatorio
url string obligatorio
posterUrl string,null obligatorio
embedProvider "youtube" | "vimeo" | "loom" | null obligatorio
embedId string,null obligatorio
caption string,null obligatorio
altText string,null obligatorio
position integer obligatorio
Order in the gallery, 0-indexed.; min -9007199254740991; max 9007199254740991
isCover boolean obligatorio

ProjectMediaUpload

uploadUrl string obligatorio
The single-use PUT URL to upload the raw image to.
method string obligatorio
The HTTP method to use for the upload.
expiresAt string obligatorio
When the upload URL expires (ISO 8601).
maxBytes integer obligatorio
Maximum allowed size of the upload in bytes.; min -9007199254740991; max 9007199254740991
headers object obligatorio
Required request headers to include on the upload.

Contributor

userId string obligatorio
name string obligatorio
username string,null obligatorio
image string,null obligatorio
role "OWNER" | "MAINTAINER" | "CONTRIBUTOR" obligatorio
accepted boolean obligatorio
invitedAt string (date-time) obligatorio
technologies ({ id: string (uuid); name: string })[] obligatorio
Which of the project's technologies this person used here. Empty while pending.
skills ({ id: string (uuid); name: string })[] obligatorio
The skills this person recorded for their work here. Empty while pending.

Story

projectId string (uuid) obligatorio
id string obligatorio
userId string obligatorio
author { name: string,null; username: string,null; image: string,null } obligatorio
problem string obligatorio
approach string obligatorio
corrections string,null obligatorio
hindsight string,null obligatorio
practices ({ technologyId: string (uuid); tool: string; toolApproved: boolean; role: "EXPLORED_OPTIONS" | "WROTE_FIRST_DRAFT" | "REVIEWED_MY_WORK" | "DID_REPETITIVE_PART" | "BUILT_END_TO_END" | "SOMETHING_ELSE"; askedFor: string })[] obligatorio
links ({ label: string; url: string })[] obligatorio
updatedAt string (date-time) obligatorio