Create link
Creates a link between a persona and another record, delegating to the shared common/links helper. The persona side is fixed: rec_type_x is always the persona record type and rec_id_x is the persona_id from the body. active IS IGNORED. CreateLinkUtil hardcodes Active: true, so the link comes back active whatever the body asked for. metadata.relation is overwritten with "personas-><other type>" as well — the registered record type name is the plural personas, not persona. rec_type_name wins over rec_type_id: the helper resolves the name when it is present and only falls back to the id otherwise. With neither, the reply is 400 common.invalid_input.
Authorization
bearerAuth In: header
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Body of POST /v1/persona-links. The persona side is fixed by the handler: rec_id_x is persona_id and rec_type_x is the persona record type, so the stored link always has the persona on the x side. The Go struct also embeds BaseModel, so id, created_at, created_by, modified_at and modified_by are decoded and then ignored.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/v1/persona-links" \ -H "Content-Type: application/json" \ -d '{ "persona_id": "84321d19-6cb7-45af-a8d3-0bb38b11a872", "rec_id": "0ba687c4-349e-490d-969f-fd374e232d42" }'{
"rec_idx": "fa292dda-ae2a-45ee-b97b-e8ab8329b907",
"rec_type_x": "5037db46-337a-4e82-97d6-129819a818a7",
"rec_idy": "f9543843-55a0-4858-ae41-eb146ddf8536",
"rec_type_y": "4f9a126c-2c2a-4b25-91ed-5614db497338",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"created_at": "2019-08-24T14:15:22Z",
"created_by": "ee824cad-d7a6-4f48-87dc-e8461a9201c4",
"modified_at": "2019-08-24T14:15:22Z",
"modified_by": "e8d4374d-93a1-4e98-a6c6-fdcf00c5059f",
"active": true,
"metadata": {}
}{
"status": 400,
"message": "Failed to serialize",
"code": "personas_m.failed_to_serialize",
"class": "validation"
}{
"status": 401,
"message": "Unauthorized",
"code": "common.unauthorized",
"class": "business"
}{
"status": 403,
"message": "No access to the record",
"code": "common.rbac_no_rec_access",
"class": "business"
}{
"status": 429,
"message": "Rate limit exceeded",
"code": "rate_limits_m.exceeded",
"class": "temporary",
"retryable": true
}{
"status": 500,
"message": "Internal server error",
"code": "common.server_error",
"class": "business"
}{
"overall_status": "unhealthy",
"message": "Service is shutting down",
"timestamp": "2026-08-27T15:04:05Z"
}Description
Previous Page
Links with the persona record type ON EITHER SIDE, as a BARE ARRAY — no envelope and no pagination. No query parameter is read. THE RESULT IS RBAC-SCOPED, not the complete set. A caller holding read_all on the link record type gets every link whose rec_type_x or rec_type_y is the persona type. Any other caller gets only links touching a persona the caller or one of their roles holds a grant on in rbac.record_permissions — so two callers legitimately see different arrays, and a client must not cache this as the full list. The empty responses differ in shape: a caller with grants but no matching links gets [], while a caller with no persona grants at all short-circuits before the query and gets null.