Recoup

Get started with Recoup.

API REFERENCE

Confirm Professional Roster Addition

On this page
POST/api/organizations/professionals

Requires explicit operator identity confirmation and organization roster intent. Use new only after confirming a distinct professional, including resolving same-name candidates; never infer identity from a name. Use existing with a professional_id from this organization to add roles without renaming. Both songwriter and producer can belong to one record. This operation creates no login account, shared canonical identity, catalog rights, enrichment job, or cross-workspace context. Research/name intake alone never calls this operation. Membership is rechecked before idempotency replay. Legacy MCP equivalent (API key or Privy token): confirm_professional_roster. Not exposed through delegated OAuth MCP. Returns the original saved response on retry, including its created flag and original status (201 for a new record, 200 for an existing record).

Authentication

bearerAuth bearer

x-api-key in header

Request

cURL
curl --request POST \
  --url 'https://api.recoupable.dev/api/organizations/professionals' \
  --header 'Authorization: Bearer YOUR_TOKEN' \
  --header 'Content-Type: application/json' \
  --data '{}'

Try it

Fill in the fields, send the request from your browser, and read the live response. The curl below updates as you type.

Kept in this browser tab only and cleared when it closes.

cURL for this request
curl --request POST \
  --url 'https://recoup-api.vercel.app/api/organizations/professionals' \
  --header 'Content-Type: application/json' \
  --data '{}'

Request body required

application/json

organization_idstringrequired

format: uuid

idempotency_keystringrequired

Generate once per deliberate operation. Persist and reuse after a timeout or lost response. Scoped to the organization and actor. Different input with the same key is rejected.

format: uuid

modestring · enumrequired

Values: "new", "existing"

namestring

minLength: 2 · maxLength: 200

professional_idstring

format: uuid

rolesarray<string · enum>required

minItems: 1 · maxItems: 2

Item properties for roles

string · enum · "songwriter", "producer"

confirmedboolean · enumrequired

Values: true

roster_intentstring · enumrequired

Values: "add"

oneOf · object 1
modestring · enum

Values: "new"

oneOf · object 2
modestring · enum

Values: "existing"

Responses

200Existing professional roles saved, or replayed existing-record operation

application/json

professionalobjectrequired
Properties for professional
idstringrequired

format: uuid

organization_idstringrequired

format: uuid

namestringrequired
rolesarray<string · enum>required
Item properties for roles

string · enum · "songwriter", "producer"

confirmed_bystringrequired

format: uuid

confirmation_basisstring · enumrequired

Operator assertion for this organization; not a globally verified person identity.

Values: "operator_confirmed"

created_atstringrequired

format: date-time

updated_atstringrequired

format: date-time

createdbooleanrequired
201New professional saved, or replayed new-record operation

application/json

professionalobjectrequired
Properties for professional
idstringrequired

format: uuid

organization_idstringrequired

format: uuid

namestringrequired
rolesarray<string · enum>required
Item properties for roles

string · enum · "songwriter", "producer"

confirmed_bystringrequired

format: uuid

confirmation_basisstring · enumrequired

Operator assertion for this organization; not a globally verified person identity.

Values: "operator_confirmed"

created_atstringrequired

format: date-time

updated_atstringrequired

format: date-time

createdbooleanrequired
400Invalid or unconfirmed request

application/json

errorstring
401Authentication required

application/json

errorstring
403Organization access denied, revoked, or record outside this organization

application/json

errorstring
409Request key already used for different input or actor

application/json

errorstring
503Unavailable storage or unconfirmed response; retry with the same key and input

application/json

errorstring

Full specification

Download the OpenAPI file for complete schemas, constraints, and examples.

Download accounts.json
View operation source
json
{
  "summary": "Confirm professional roster addition",
  "description": "Requires explicit operator identity confirmation and organization roster intent. Use new only after confirming a distinct professional, including resolving same-name candidates; never infer identity from a name. Use existing with a professional_id from this organization to add roles without renaming. Both songwriter and producer can belong to one record. This operation creates no login account, shared canonical identity, catalog rights, enrichment job, or cross-workspace context. Research/name intake alone never calls this operation. Membership is rechecked before idempotency replay. Legacy MCP equivalent (API key or Privy token): confirm_professional_roster. Not exposed through delegated OAuth MCP. Returns the original saved response on retry, including its created flag and original status (201 for a new record, 200 for an existing record).",
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyAuth": []
    }
  ],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "organization_id": {
              "type": "string",
              "format": "uuid"
            },
            "idempotency_key": {
              "type": "string",
              "format": "uuid",
              "description": "Generate once per deliberate operation. Persist and reuse after a timeout or lost response. Scoped to the organization and actor. Different input with the same key is rejected."
            },
            "mode": {
              "type": "string",
              "enum": [
                "new",
                "existing"
              ]
            },
            "name": {
              "type": "string",
              "minLength": 2,
              "maxLength": 200
            },
            "professional_id": {
              "type": "string",
              "format": "uuid"
            },
            "roles": {
              "type": "array",
              "minItems": 1,
              "maxItems": 2,
              "items": {
                "type": "string",
                "enum": [
                  "songwriter",
                  "producer"
                ]
              }
            },
            "confirmed": {
              "type": "boolean",
              "enum": [
                true
              ]
            },
            "roster_intent": {
              "type": "string",
              "enum": [
                "add"
              ]
            }
          },
          "required": [
            "organization_id",
            "idempotency_key",
            "mode",
            "roles",
            "confirmed",
            "roster_intent"
          ],
          "oneOf": [
            {
              "properties": {
                "mode": {
                  "enum": [
                    "new"
                  ]
                }
              },
              "required": [
                "name"
              ],
              "not": {
                "required": [
                  "professional_id"
                ]
              }
            },
            {
              "properties": {
                "mode": {
                  "enum": [
                    "existing"
                  ]
                }
              },
              "required": [
                "professional_id"
              ],
              "not": {
                "required": [
                  "name"
                ]
              }
            }
          ]
        }
      }
    }
  },
  "responses": {
    "200": {
      "description": "Existing professional roles saved, or replayed existing-record operation",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "required": [
              "professional",
              "created"
            ],
            "properties": {
              "professional": {
                "$ref": "#/components/schemas/OrganizationProfessional"
              },
              "created": {
                "type": "boolean"
              }
            }
          }
        }
      }
    },
    "201": {
      "description": "New professional saved, or replayed new-record operation",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "required": [
              "professional",
              "created"
            ],
            "properties": {
              "professional": {
                "$ref": "#/components/schemas/OrganizationProfessional"
              },
              "created": {
                "type": "boolean"
              }
            }
          }
        }
      }
    },
    "400": {
      "description": "Invalid or unconfirmed request",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "401": {
      "description": "Authentication required",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "403": {
      "description": "Organization access denied, revoked, or record outside this organization",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "409": {
      "description": "Request key already used for different input or actor",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "503": {
      "description": "Unavailable storage or unconfirmed response; retry with the same key and input",
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "error": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}