Skip to content

People search

This guide covers the person-centred read: find a holder or representative and see how much of the register is theirs. It complements field-scoped search, where people are a filter over marks; here they are the subject of the query.

The complete, always-current per-field schema lives in the interactive OpenAPI reference at /docs (Scalar). This guide explains the contract and links to that reference — it does not restate the schema. When a field is not documented here, /docs is authoritative.

Throughout, the base URL is written as $TARNO_BASE_URL and the key as $TARNO_API_KEY, and every call carries the X-API-Key header.

GET /v1/personas · scope brands:read · MCP equivalent: search_personas

Until now people could only be used as a filter over marks (?titular=, ?rut=) or as an aggregate (/v1/insights/by-holder). This endpoint inverts the question: it starts from the person and tells you how much of the register is theirs.

curl -sS "$TARNO_BASE_URL/v1/personas?q=carey" -H "X-API-Key: $TARNO_API_KEY"
[
  {
    "id": "1261017",
    "nombre": "ESTUDIO CAREY LIMITADA",
    "identificador": "76111111-6",
    "pais": "CL",
    "region": "13",
    "comuna": "13101",
    "marcasTitular": 12,
    "marcasRepresentante": 3480,
    "marcasTotal": 3492,
    "marcasHistoricas": 0,
    "tipo": "juridica",
    "tipoOrigen": "rut",
    "observacion": null,
    "nombrePublicado": "Estudio Carey Limitada",
    "revision": false
  },
  {
    "id": "884213",
    "nombre": "JUAN CAREY SOTO",
    "identificador": null,
    "pais": "CL",
    "region": null,
    "comuna": null,
    "marcasTitular": 1,
    "marcasRepresentante": 0,
    "marcasTotal": 1,
    "marcasHistoricas": 0,
    "tipo": "desconocido",
    "observacion": null,
    "nombrePublicado": "Juan Carey Soto",
    "revision": false
  }
]
Parameter What it does
q Partial, accent-insensitive match over name and surname. Minimum 2 characters — argandona finds Argandoña.
rut Exact match. Accepts any format (17.271.415-3, 17271415-3) and normalises it.
limit / offset Paging. limit defaults to 25, caps at 100.
envelope true adds the { data, dataAsOf } envelope.

You must supply q or rut; with neither, the response is 400 — so nobody lists the whole table by accident.

Results are ordered by mark volume, heaviest first. When you search a common surname, the firm with thousands of marks comes before its one-mark namesake.

The counts are CURRENT, and marcasHistoricas tells you what is missing

marcasTitular, marcasRepresentante and marcasTotal count only what the person holds today. Transfer a mark away and it stops counting.

marcasHistoricas counts what they used to hold and no longer do. It exists so that subtraction is never silent: without it you would see a smaller number and nothing to say history exists. It is 0 for almost everyone; a non-zero value is the cue to ask for the history:

# the marks this person USED to hold
curl -sS "$TARNO_BASE_URL/v1/brands?titular=Carey&vigencia=historica" -H "X-API-Key: $TARNO_API_KEY"

What KIND of party each person is

Since 2026-09-08 every person carries five more fields, the same five in all three places where the contract publishes a person: the brand detail (GET /v1/brands/:nroSolicitud), the registrability report and this search. They are additive: no earlier field was removed, renamed or re-typed, and no scope changed — they are read under the same brands:read — so an integration written before that date keeps parsing every response unchanged.

Field Type What it says
tipo natural | juridica | desconocido What kind of party this is.
tipoOrigen rut | sufijo | manual Which signal produced tipo. Omitted — never null — when there was none.
observacion string | null The jurisdiction clause INAPI writes glued to the name.
nombrePublicado string | null The spelling exactly as INAPI published it, against the canonical nombre.
revision boolean A known ambiguity is attached to this row.

All five are declared optional in the schema — that is what makes the change additive — and tipoOrigen additionally disappears from the object when there is no signal.

desconocido is a value, not a hole. Measured in production on 2026-09-07 over 396,287 people: 127,263 carry a RUT (79,385 natural, 47,878 jurídica), another 167,568 carry a company suffix in the name, and roughly a third of the corpus carries neither signal. That third is desconocido, and saying so is more honest than deducing. Reading it as "probably a natural person" would sweep some 130,000 unclassified parties into a tipo = 'natural' filter. When you need certainty, require tipoOrigen: 'rut' — the cut the state itself applies when it issues the number — instead of accepting a deduction from a word at the end of a name.

tipoOrigen is omitted; it never arrives as null. With no signal the key disappears from the object, which is exactly when tipo reads desconocido (the second element of the example above has no tipoOrigen). An if (p.tipoOrigen === null) never fires: the correct check is p.tipoOrigen === undefined or !("tipoOrigen" in p).

nombre is the field to SEARCH with; nombrePublicado is the field to SHOW, or to CHECK against a source document. nombre is the canonical form — UPPERCASE with accents — and it is what the engine indexes; nombrePublicado keeps the source's own spelling so any value can be traced back to INAPI. Matching on nombrePublicado re-introduces exactly the case-and-accent noise the canonical form exists to remove.

observacion is INAPI's prose, not a note of ours. It is the jurisdiction clause lifted out of the name: «X, SOCIEDAD ORGANIZADA BAJO LAS LEYES DEL ESTADO DE DELAWARE» is stored as nombre: 'X' plus this observation. It is published verbatim, misspellings included: 1,472 people carry it in 681 distinct spellings of the same clause (SOCIEDD ORGANIZADA…, SOC. ORG. BAJO LAS LEYES…). Do not parse it as a controlled vocabulary; it is prose.

revision warns, it does not disqualify. It means the corpus itself flagged the row for a human to look at — a RUT that contradicts the company suffix in the name, a clause that ate the whole name — not that the data is bad. Whoever shows the party to a lawyer may want to say so; whoever counts marks can ignore it. The reason is not published: it is operator vocabulary that grows with every pass, so the contract answers only the question a consumer actually has — "can I trust this row blindly?".

The people corpus was rewritten on 2026-09-08

Names are canonical from that date: 396,444 people were rewritten to the canonical form and some 240,000 changed spelling. If you compare values cached before then against what the API returns today, you will see case and accent differences that are not data changes. Also:

  • Jurisdiction clauses are no longer inside nombre: they live in observacion, and the name they were glued to is now just the name.
  • Grouping or de-duplicating people on your side by nombre over-counted: the same party that read Estudio Carey Limitada on one mark and ESTUDIO CAREY LIMITADA on another now reads the same on both.
  • 179 duplicate groups were fused. No mark changed hands, so a party's total can only go up by absorbing its twin, never down.

Two things worth understanding

It returns counts, not marks. A large firm holds thousands: embedding them would make the response unbounded and duplicate the search engine /v1/brands already is. To get a person's marks, use the values returned here:

# every mark this party is on, by RUT (any role)
curl -sS "$TARNO_BASE_URL/v1/brands?rut=76111111-6" -H "X-API-Key: $TARNO_API_KEY"

# only where they are the holder, by name
curl -sS "$TARNO_BASE_URL/v1/brands?titular=Carey" -H "X-API-Key: $TARNO_API_KEY"

# what they used to hold and no longer do (`vigencia=todas` spans both)
curl -sS "$TARNO_BASE_URL/v1/brands?titular=Carey&vigencia=historica" -H "X-API-Key: $TARNO_API_KEY"

Those calls return current holding by default: a party that transferred a mark away drops out of it. vigencia changes the question — see field-scoped search.

identificador is often null, and that is not a data defect. The RUT is a Chilean identifier, so:

  • a foreign holder will never have one — it does not exist;
  • for filings before 2023 INAPI did not publish it (17-26% coverage across 2017-2022, against ~75% from 2024 onwards).

If your integration joins on RUT, treat null as "not available", never as "no match".

From an AI agent

search_personas(q: "carey", limit: 5)
search_personas(rut: "17.271.415-3")

The MCP tool always returns the { data, dataAsOf } envelope and is byte-identical to GET /v1/personas?envelope=true.