# Split a full name into first and last name

Plain-Markdown twin of <https://gender-api.com/en/split-first-and-last-name>.
Last reviewed 2026-09-01. Prices are rendered live on the HTML page.

One combined name field, one API call, two clean fields — with the particles, titles and
reversed order that break a hand-written split already handled, and the gender in the same
response.

## The short answer

- Send the combined field, get back `first_name` and `last_name` — plus the gender, the
  accuracy and the sample count, in the same response, for **one credit**.
- Nobiliary particles (`van der`, `von den`, `de la`) and academic and job titles are
  handled rather than tripped over — and a reversed `Rossi, Andrea` resolves too, from the
  name data rather than from the comma.
- Where both halves could be either, the decision comes from how often each part occurs as
  a first name against how often it occurs as a surname — **not** from its position in the
  string.
- **Strict mode** returns an empty last name instead of a guess when the surname is not in
  the database, so you can see the gap. Strict mode is a **v1 parameter only**.

## Why splitting on the space does not work

Almost every codebase has a version of this: take the name field, split on whitespace,
first element is the first name, last element is the surname. It passes review because the
test data is English, and it goes wrong quietly on the first customer who is not.

The same name, three rules:

| Rule | `first_name` | `last_name` | Verdict |
|---|---|---|---|
| split on the first space | `Anna` | `van` | wrong |
| split on the last space | `Anna van der` | `Berg` | wrong |
| particles, then both name databases | `Anna` | `van der Berg` | correct |

The failure mode is what makes it expensive. Nothing raises an exception. You get a
database full of people whose surname is `van`, a mail merge that greets them by it, and no
log line pointing at the cause.

## What decides the split

Four things, in order — and the last of them is the one a rule-based splitter cannot have,
because it needs to know how names are actually distributed.

1. **Titles come off first.** `Prof. Dr.`, `Dipl.-Ing.`, `Managing Director` and the rest of
   a maintained list are removed before anything else is decided, so they never end up in a
   name field.
2. **Particles stay with the surname.** `van`, `van der`, `van den`, `von`, `von der`, `de`,
   `de la`, `du`, `le`, `di`, `des` and their neighbours are recognised as part of the
   surname they belong to.
3. **Punctuation is not trusted to carry the order.** The comma in `Rossi, Andrea` is
   stripped along with the titles, and the order is then read from the name data — a comma
   is a formatting habit and plenty of lists use it inconsistently. In the CSV/Excel upload
   you can state the column's order outright, and a stated order is used as stated.
4. **Ambiguity is settled by the data.** Each candidate part is looked up in both the
   first-name and the last-name database, and the part that behaves far more like a surname
   than a first name is the surname.

Pass a country code and the same comparison happens against that country rather than
against every country at once.

Four forms the field arrives in:

| What arrives | What decides it | What comes back |
|---|---|---|
| `Rossi, Andrea` | the comma is stripped; the order is read from the data, not from position | `Andrea` / `Rossi` |
| `Prof. Dr. Anna Maria de la Cruz` | titles stripped; particle stays with the surname; both given names kept | `Anna Maria` / `de la Cruz` |
| `Andrea Rossi` (both parts plausible) | first-name frequency against surname frequency; position does not decide it | `Andrea` / `Rossi` |
| `Markus Stefan Nonexistent`, strict on | surname not in the database, and strict mode says do not invent one | `Markus Stefan` / *empty* |

## How to call it

### v2 — the current API

```
POST https://gender-api.com/v2/gender/by-full-name
Authorization: Bearer <token>
Content-Type: application/json

{ "full_name": "Anna van der Berg", "country": "NL" }
```

```json
{
    "result_found": true,
    "first_name": "Anna",
    "last_name": "van der Berg",
    "gender": "female",
    "probability": 0.98,
    "details": { "credits_used": 1, "samples": 8961, "duration": "33ms" }
}
```

Reference: <https://gender-api.com/en/api-docs/v2/query-by-full-name>

### v1 — when you need strict mode

Strict mode exists on the v1 split endpoint only. If an empty last name matters more to you
than being on the newer API, use this one.

```
GET https://gender-api.com/get?split=Anna%20van%20der%20Berg&strict=true&key=<key>
```

Reference: <https://gender-api.com/en/api-docs/split-first-and-last-name>

Official clients for PHP, Python, Node, Java, Go, Ruby, Rust, Perl and .NET:
<https://gender-api.com/en/clients>

## First, is that column even full names?

Worth knowing before you process a file you did not create. Send a sample of up to 100
values and you get back whether they look like full names — and it costs **no credits**.

```
POST https://gender-api.com/v2/name-format-detect

{ "names": ["Sophie Jones", "Lorenzo Carlos", "Anna van der Berg"] }
```

```json
{
    "is_fullname": true,
    "fullname_probability": 1,
    "validHints": [ "…" ]
}
```

Be clear about what this measures: `fullname_probability` is the share of the values you
sent that consist of more than one word, and `is_fullname` is that share above 0.6. It is a
judgement about the **column**, not about each name — which is exactly what you need when
deciding whether to split at all, and not a substitute for the split itself.

A mixed column is a real answer too: some lists hold `Thomas` and `John Smith` side by
side, and the split handles both without you sorting them first.

## Where it still needs your help

A splitter that claimed to handle every name in the world would be lying. These are the
cases where no rule resolves the string on its own.

If you control the form, the cheapest fix is not an API at all: two fields instead of one,
or a hint that the format is "first name, last name". Everything below is what to do when
you do not control it.

- **Surname first.** Whether or not a comma is there, the reading the name data supports
  wins over a rule about position — right far more often than not, but not a guarantee. If
  you know the whole column is surname-first, state that in the upload rather than relying
  on the punctuation.
- **Single-word names.** A mononym has no surname to find. The last name comes back empty
  rather than the first name being cut in half.
- **Inconsistent transliteration.** The same name spelled three ways across a list resolves
  as three names, because that is what it is in the data.
- **Compound given names without a hyphen.** `Anna Maria` is kept together where the data
  supports it, but a list mixing `Anna Maria Rossi` and `Anna Rossi` will not be uniform.

In all four, a country code narrows the problem, and strict mode makes the uncertain rows
visible instead of quietly plausible. An empty field you can filter beats a wrong one you
cannot spot.

## A whole column at once

If the names are in a spreadsheet rather than an application, you do not need the API.
Upload the file, point at the column that holds the combined names, and the split parts
come back as new columns beside your data — up to 10,000,000 rows per CSV or 100,000 per
Excel workbook, and your workbook returned intact (styles, dates, formulas, merged cells,
other worksheets).

- Upload a CSV or Excel file: <https://gender-api.com/en/genderize-excel-and-csv-files>
- Limits, price at volume and procurement answers:
  <https://gender-api.com/en/bulk-gender-lookup>

## FAQ

**Why not just split on the space?**
Because the space is not the boundary. `Anna van der Berg` splits into a surname of `van`
on the first space and a first name of `Anna van der` on the last one. Both are wrong, and
both fail silently.

**What happens when the surname is not in the database?**
That is what strict mode is for, on the v1 endpoint. With it on, the last name comes back
empty rather than guessed. With it off, a best-effort surname is extracted anyway.

**Does it also give me the gender?**
Yes, in the same response and for the same one credit — along with the sample count and the
accuracy behind it. Splitting and gendering is one call, not two.

**How do I know whether my column holds full names at all?**
`POST /v2/name-format-detect` with up to 100 sample values. It costs no credits.

**What does splitting cost?**
One credit per name, the same as a plain gender lookup. Credits are bought in advance and
do not expire.

**Will it handle names that are not Western?**
Partly, and it is better to know where the edges are — see "Where it still needs your
help". Sending a country code helps.

## Start

100 free lookups a month, no credit card: <https://gender-api.com/en/account/overview>
