PHPackages                             survos/nara-php-api - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. survos/nara-php-api

ActiveLibrary[API Development](/categories/api)

survos/nara-php-api
===================

PHP client for NARA's Catalog API v2

1.3.1(4w ago)0118↓75%MITPHPPHP ^8.4CI failing

Since Mar 31Pushed 4w agoCompare

[ Source](https://github.com/survos/nara-php-api)[ Packagist](https://packagist.org/packages/survos/nara-php-api)[ GitHub Sponsors](https://github.com/kbond)[ RSS](/packages/survos-nara-php-api/feed)WikiDiscussions main Synced 6d ago

READMEChangelogDependencies (15)Versions (6)Used By (0)

NARA Catalog PHP API
====================

[](#nara-catalog-php-api)

A PHP client for the [National Archives Catalog API v2](https://catalog.archives.gov/api/v2/).

Installation
------------

[](#installation)

```
composer require survos/nara-php-api
```

This library requires Symfony HTTP Client (included as a dependency).

Quick Start
-----------

[](#quick-start)

```
use Survos\Nara\ClientFactory;

$client = ClientFactory::create($yourApiKey);

// Search records (raw array response)
$results = $client->search(['q' => 'constitution']);
echo $results['body']['hits']['total']['value'];

// Search with typed DTOs
$results = $client->searchWithDtos(['q' => 'constitution']);
foreach ($results as $result) {
    echo $result->record->title;
    echo $result->record->naId;
}

// Search transcriptions
$transcriptions = $client->transcriptionsSearchWithDtos(['q' => 'constitution']);
foreach ($transcriptions as $t) {
    echo $t->contribution;
}

// Get single record by NA ID
$record = $client->getRecordByNaId(1667751);
echo $record->title;
```

Contributing data (write)
-------------------------

[](#contributing-data-write)

The Catalog API can also write contributions — **transcriptions**, **tags**, and **comments** — back to the National Archives. This is how you give OCR or human-keyed text a permanent home in the national record.

```
use Survos\Nara\ClientFactory;

// Writes need your API key *and* your Catalog user UUID (the contribution
// is attributed to that account). Set it once on the client...
$client = ClientFactory::create($yourApiKey, userId: $yourCatalogUuid);

// Submit the full text of a digital object as a transcription. A transcription
// attaches to one digital object (a single page/image), so you pass both the
// record's naId AND that object's id. Re-submitting overwrites the object's
// transcription (NARA keeps history).
$result = $client->submitTranscription(
    targetNaId: 170821856,
    transcription: $ocrText,
    targetObjectId: 170821859,
);

if ($result->success) {
    echo "Saved as contribution {$result->contributionId}";
} else {
    // 401/422 etc. are returned (not thrown) so a bulk loop can log & continue.
    echo "Failed (HTTP {$result->statusCode}): {$result->message}";
}

// Tags and comments attach at the record level:
$client->submitTag(521451, 'president');
$client->submitComment(521451, 'This photo also appears in series ...');

// Or pass the user UUID per call instead of on the client:
$client->submitTranscription(170821856, $ocrText, 170821859, userId: $someOtherUuid);
```

These map to `POST /api/v2/{transcriptions,tags,comments}` with a JSON body of `{ , targetNaId, userId }` — transcriptions also require `targetObjectId` (the specific digital object the text belongs to).

#### Finding the `targetObjectId`

[](#finding-the-targetobjectid)

A record (`naId`) can hold many digital objects (pages/images), each with its own `objectId`. To transcribe page by page, list the objects first and submit one transcription per object:

```
foreach ($client->getDigitalObjects(170821856) as $object) {
    // $object is a Survos\Nara\Model\DigitalObject
    $text = $ocrByObjectId[$object->objectId] ?? null;
    if ($text !== null) {
        $client->submitTranscription(170821856, $text, $object->objectId);
    }
}
```

To discover your Catalog user UUID (or check an object's current transcription before overwriting), search existing contributions:

```
$mine = $client->contributionsSearch(['userName' => 'yourCatalogUsername']);
// read the `userId` off any returned contribution
```

### Enabling write access

[](#enabling-write-access)

Write access is **not** enabled on a standard read key. Email [Catalog\_API@nara.gov](mailto:Catalog_API@nara.gov) with your email and Catalog username to have contributions enabled for your key. You also need your Catalog **user UUID** — find it in the `userId` field of any of your existing contributions (e.g. `GET /api/v2/contributions/search`).

### CLI: `bin/contribute.php`

[](#cli-bincontributephp)

A safe demo command — **dry-run by default**, it only writes when you pass `--force`:

```
export NARA_API_KEY="your-key"
export NARA_USER_ID="your-catalog-uuid"

# Preview exactly what would be sent (no write):
php bin/contribute.php transcription 170821856 --object-id 170821859 --text "Dear Sir, ..."

# Read the text from a file:
php bin/contribute.php transcription 170821856 --object-id 170821859 --text-file page1.txt

# Pipe OCR output straight in, then actually submit:
mistral-ocr page1.png | php bin/contribute.php transcription 170821856 --object-id 170821859 --force
```

API Key
-------

[](#api-key)

To get an API key, email [Catalog\_API@nara.gov](mailto:Catalog_API@nara.gov).

Demo
----

[](#demo)

A CLI demo is included:

```
# Using environment variable
export NARA_API_KEY="your-key"
php bin/search.php search "constitution"

# Using --api-key option
php bin/search.php search "constitution" --api-key=your-key
php bin/search.php search "presidents" --limit=5

# Lookup by NA ID
php bin/search.php search 1667751

# Verbose output
php bin/search.php search "constitution" -vvv --limit=1
```

Bulk Data
---------

[](#bulk-data)

For large-scale data access, NARA provides bulk downloads on AWS S3:

```
# Download full descriptions (87 GB)
aws s3 cp s3://nara-national-archives-catalog/zip/nac_export_descriptions_2025-04-08.zip ./ --no-sign-request

# Sync specific record group
aws s3 sync s3://nara-national-archives-catalog/descriptions/record-groups/rg_011/ ./rg011/ --no-sign-request
```

See [NARA Developer Docs](https://www.archives.gov/developer/national-archives-catalog-dataset) for more.

License
-------

[](#license)

MIT License - see [LICENSE](LICENSE.md) file.

###  Health Score

45

—

FairBetter than 91% of packages

Maintenance94

Actively maintained with recent releases

Popularity13

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity56

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~27 days

Total

5

Last Release

28d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/21b39551f92ed4143772c622f9e571589c5a72c96ab3c53fe67489ce0d83e806?d=identicon)[tacman1123](/maintainers/tacman1123)

---

Top Contributors

[![tacman](https://avatars.githubusercontent.com/u/619585?v=4)](https://github.com/tacman "tacman (7 commits)")

---

Tags

apiclientsdkswaggeropenapicatalogarchivesnara

###  Code Quality

Code StylePHP CS Fixer

### Embed Badge

![Health badge](/badges/survos-nara-php-api/health.svg)

```
[![Health](https://phpackages.com/badges/survos-nara-php-api/health.svg)](https://phpackages.com/packages/survos-nara-php-api)
```

###  Alternatives

[jolicode/slack-php-api

An up to date PHP client for Slack's API

2554.9M13](/packages/jolicode-slack-php-api)[api-platform/openapi

Models to build and serialize an OpenAPI specification.

425.3M110](/packages/api-platform-openapi)[api-platform/json-schema

Generate a JSON Schema from a PHP class

325.3M89](/packages/api-platform-json-schema)[bitrix24/b24phpsdk

An official PHP library for the Bitrix24 REST API

10250.3k6](/packages/bitrix24-b24phpsdk)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
