postlake-dev Profiles API

Named groupings of social accounts

Operations 4

PATCH /v1/profiles/{id} Rename profile #
DELETE /v1/profiles/{id} Delete profile #
POST /v1/profiles Create profile #
GET /v1/profiles List profiles #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/postlake-dev:postlake-dev-profiles-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

postlake-dev-profiles-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: PostLake Profiles API
  version: 1.0.0
  description: Unified social media API. One API key, 10 platforms, normalised responses. Built for agents and developers.
  contact:
    url: https://postlake.dev
servers:
- url: https://api.postlake.dev
security:
- bearerAuth: []
tags:
- name: Profiles
  description: Named groupings of social accounts
paths:
  /v1/profiles/{id}:
    parameters:
    - name: id
      in: path
      required: true
      schema:
        type: string
    patch:
      tags:
      - Profiles
      summary: Rename profile
      description: Rename a profile. The id is unchanged, so connected channels and posts are untouched, but the slugified identifier moves with the name. The response reports `previousUsername` and `usernameChanged` so anything addressing the profile by its old name can be updated.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
              required:
              - name
      responses:
        '200':
          description: Renamed
          content:
            application/json:
              schema:
                type: object
                properties:
                  profile:
                    $ref: '#/components/schemas/Profile'
                  previousUsername:
                    type: string
                  usernameChanged:
                    type: boolean
        '400':
          description: Invalid name, no such profile, or the name is taken
        '401':
          $ref: '#/components/responses/Unauthorized'
      operationId: patchV1ProfilesById
      x-operation-id-source: derived
    delete:
      tags:
      - Profiles
      summary: Delete profile
      description: Delete a profile. This ALSO disconnects every channel in it, and reconnecting each one requires its owner to approve access on that network again. It therefore refuses with 400 while channels are attached, naming them, unless `?force=true` is passed.
      parameters:
      - name: force
        in: query
        required: false
        schema:
          type: boolean
        description: Go ahead even though channels will be disconnected.
      responses:
        '200':
          description: Deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  deleted:
                    type: boolean
                  disconnected:
                    type: array
                    items:
                      type: string
                    description: The channels that went with it.
        '400':
          description: No such profile, or channels are attached and force was not set
        '401':
          $ref: '#/components/responses/Unauthorized'
      operationId: deleteV1ProfilesById
      x-operation-id-source: derived
  /v1/profiles:
    post:
      tags:
      - Profiles
      summary: Create profile
      description: Create a named profile. Send `name` as a person would write it (spaces and capitals are fine); it is slugified into the identifier agents address the profile by, and the original is kept for display. `username` is still accepted as an alias for `name`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: e.g. "Otaku Gems News", stored as otaku-gems-news
                username:
                  type: string
                  description: Alias for name, kept for compatibility.
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Profile'
        '400':
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
      operationId: postV1Profiles
      x-operation-id-source: derived
    get:
      tags:
      - Profiles
      summary: List profiles
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  profiles:
                    type: array
                    items:
                      $ref: '#/components/schemas/Profile'
                required:
                - profiles
        '401':
          $ref: '#/components/responses/Unauthorized'
      operationId: getV1Profiles
      x-operation-id-source: derived
components:
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          $ref: '#/components/schemas/NormalisedError'
      required:
      - error
    NormalisedError:
      type: object
      description: '`type` is the coarse category you route on and is deliberately small, so it cannot say WHICH input was wrong. `code`, `fix`, `docs` and `param` are what turn a rejection into something a caller can act on rather than guess at. They are optional only in the sense that not every error has all four.'
      properties:
        type:
          type: string
          description: Coarse category to route on, e.g. rate_limited, auth_expired, platform_rejected.
        message:
          type: string
        platform:
          oneOf:
          - $ref: '#/components/schemas/Platform'
          - type: 'null'
        retryable:
          type: boolean
        code:
          type: string
          description: Stable, granular handle to branch on, e.g. text_too_long. Also the anchor in the error reference.
        fix:
          type: string
          description: The next action, in plain words. Safe to show a person as-is.
        docs:
          type: string
          format: uri
          description: Where the rule is written down, so it is learned once rather than rediscovered.
        param:
          type: string
          description: The request field at fault, so a form can mark the right input.
      required:
      - type
      - message
      - retryable
    Platform:
      type: string
      enum:
      - bluesky
      - threads
      - x
      - linkedin
      - instagram
      - tiktok
      - facebook
      - youtube
      - pinterest
    Profile:
      type: object
      properties:
        id:
          type: string
        username:
          type: string
          description: The identifier agents put in `profile:`. Slugified.
        name:
          type: string
          description: What the person typed, for display. Absent on profiles created before this existed.
        createdAt:
          type: string
          format: date-time
      required:
      - id
      - username
      - createdAt
  responses:
    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              type: unauthorized
              message: missing or invalid api key
              retryable: false