--- title: Prefix Management API nextjs: metadata: title: Prefix Management API description: Learn how to manage namespace prefixes in TerminusDB to simplify your document IRIs and organize your data vocabularies. keywords: prefix, namespace, IRI, REST API, CRUD, vocabulary, semantic web alternates: canonical: https://terminusdb.org/docs/prefix-management --- ## What You'll Learn This guide teaches you how to manage namespace prefixes in TerminusDB. You'll learn: - **What** prefixes are and why they matter - **When** to use each operation (GET, POST, PUT, DELETE) - **How** to add, update, and remove prefixes safely - **Best practices** for organizing your data vocabularies ## What Are Prefixes? Prefixes are shorthand aliases for long namespace URIs. They make your documents cleaner and easier to read. There are default prefixes in TerminusDB that are normally relatively invisible, the `@base`, and `@schema` prefixes that are tied to TerminusDB. Instead of using the built in prefixes, it's also possible to use global standards and setup the TerminusDB data product to align with standard ontologies. **Without prefixes:** ```json { "@id": "http://example.org/data/Person/alice", "@type": "http://schema.org/Person", "http://schema.org/name": "Alice" } ``` **With prefixes:** ```json { "@id": "ex:Person/alice", "@type": "schema:Person", "schema:name": "Alice" } ``` ### Why Use Prefixes? 1. **Readability**: `schema:Person` is clearer than `http://schema.org/Person` 2. **Maintainability**: Make software easier to change when prefixes change 3. **Interoperability**: Use standard vocabularies (schema.org, FOAF, Dublin Core) 4. **Organization**: Group related concepts under prefixes (`company:Employee`, `company:Department`) ## Common Use Cases ### Scenario 1: Setting Up Standard Vocabularies When starting a new database, add common prefixes for vocabularies you'll use: ```bash # Add schema.org for general types curl -X POST http://localhost:6363/api/prefix/admin/mydb/schema \ -u admin:root -H "Content-Type: application/json" \ -d '{"uri": "http://schema.org/"}' # Add Dublin Core for metadata curl -X POST http://localhost:6363/api/prefix/admin/mydb/dc \ -u admin:root -H "Content-Type: application/json" \ -d '{"uri": "http://purl.org/dc/elements/1.1/"}' ``` ### Scenario 2: Organizing Company Data Use custom prefixes to organize your domain-specific data: ```bash # Company schema curl -X POST http://localhost:6363/api/prefix/admin/mydb/company \ -u admin:root -H "Content-Type: application/json" \ -d '{"uri": "http://mycompany.com/schema/"}' # Then use in documents: company:Employee, company:Department ``` ### Scenario 3: API Version Migration Update a prefix when your API schema changes: ```bash # Update to v2 of your API schema curl -X PUT http://localhost:6363/api/prefix/admin/mydb/api \ -u admin:root -H "Content-Type: application/json" \ -d '{"uri": "http://api.mycompany.com/v2/schema/"}' ``` ## API Reference ### Base Endpoint ``` /api/prefix/{organization}/{database}/{prefix_name} ``` ### Quick Reference | Method | Use When... | What It Does | |--------|-------------|--------------| | **GET** | You need to check what a prefix expands to | Retrieves the IRI for a prefix | | **POST** | Adding a new prefix for the first time | Creates a prefix (fails if exists) | | **PUT** | Changing where an existing prefix points | Updates a prefix (fails if not exists) | | **PUT ?create=true** | You want the prefix to exist regardless | Creates OR updates (always succeeds) | | **DELETE** | Removing an unused prefix | Deletes a prefix | ## Operations ### GET - Check a Prefix **Use when:** You need to verify what IRI a prefix expands to, or check if a prefix exists before using it in documents. ```bash curl -X GET \ http://localhost:6363/api/prefix/admin/mydb/myprefix \ -u admin:root ``` **Response (200 OK):** ```json { "@type": "api:PrefixResponse", "api:prefix_name": "myprefix", "api:prefix_uri": "http://example.org/myprefix/", "api:status": "api:success" } ``` **Error (404 Not Found):** ```json { "@type": "api:PrefixErrorResponse", "api:status": "api:not_found", "api:error": { "@type": "api:PrefixNotFound", "api:prefix_name": "myprefix" }, "api:message": "Prefix 'myprefix' not found" } ``` --- ### POST - Add a New Prefix **Use when:** You're adding a prefix for the first time. This ensures you don't accidentally overwrite an existing prefix. **⚠️ Important:** This operation fails if the prefix already exists. Use PUT with `?create=true` if you want upsert behavior. ```bash curl -X POST \ http://localhost:6363/api/prefix/admin/mydb/myprefix \ -u admin:root \ -H "Content-Type: application/json" \ -d '{"uri": "http://example.org/myprefix/"}' ``` **Response (201 Created):** ```json { "@type": "api:PrefixAddResponse", "api:prefix_name": "myprefix", "api:prefix_uri": "http://example.org/myprefix/", "api:status": "api:success" } ``` **Common Errors:** | Status | Error Type | Cause | Solution | |--------|-----------|-------|----------| | 400 | `PrefixAlreadyExists` | Prefix name already in use | Use PUT to update, or DELETE then POST | | 400 | `ReservedPrefix` | Name starts with `@` | Choose different name (@ prefixes are system-reserved) | | 400 | `InvalidIRI` | URI missing scheme | Add `http://` or `https://` to the URI | **Example - Prefix Already Exists:** ```json { "@type": "api:PrefixErrorResponse", "api:status": "api:failure", "api:error": { "@type": "api:PrefixAlreadyExists", "api:prefix_name": "myprefix" }, "api:message": "Prefix 'myprefix' already exists" } ``` --- ### PUT - Update an Existing Prefix **Use when:** You need to change where an existing prefix points. For example, migrating from `http://v1.api/` to `http://v2.api/`. **⚠️ Important:** This operation fails if the prefix doesn't exist. Use PUT with `?create=true` for upsert behavior (create if missing). ```bash curl -X PUT \ http://localhost:6363/api/prefix/admin/mydb/myprefix \ -u admin:root \ -H "Content-Type: application/json" \ -d '{"uri": "http://example.org/updated/"}' ``` **Response (200 OK):** ```json { "@type": "api:PrefixUpdateResponse", "api:prefix_name": "myprefix", "api:prefix_uri": "http://example.org/updated/", "api:status": "api:success" } ``` --- ### PUT ?create=true - Upsert (Create or Update) **Use when:** You want to ensure a prefix has a specific value, regardless of whether it already exists. Perfect for initialization scripts or idempotent operations. **πŸ’‘ Tip:** Upsert is safer for automation - it always succeeds whether the prefix exists or not. ```bash curl -X PUT \ "http://localhost:6363/api/prefix/admin/mydb/myprefix?create=true" \ -u admin:root \ -H "Content-Type: application/json" \ -d '{"uri": "http://example.org/myprefix/"}' ``` **When to use upsert vs POST/PUT:** - **Upsert (`?create=true`)**: Initialization scripts, ensuring consistency - **POST**: Interactive use, want to know if prefix already exists - **PUT**: Explicit updates, want to know if prefix is missing --- ### DELETE - Remove a Prefix **Use when:** Cleaning up unused prefixes or removing deprecated namespace mappings. **⚠️ Warning:** Deleting a prefix does NOT delete documents using that prefix. Existing documents will still reference the full IRI. ```bash curl -X DELETE \ http://localhost:6363/api/prefix/admin/mydb/myprefix \ -u admin:root ``` **Response (200 OK):** ```json { "@type": "api:PrefixDeleteResponse", "api:prefix_name": "myprefix", "api:status": "api:success" } ``` --- ## Best Practices & Guidelines ### Naming Conventions **Character Rules (XML NCName - same as used throughout TerminusDB):** Prefix names must follow these rules: 1. **Start with**: Letter (`A-Z`, `a-z`) or underscore (`_`) 2. **Continue with**: Letters, digits (`0-9`), hyphen (`-`), dot (`.`), underscore (`_`) 3. **Cannot contain**: Colon (`:`) 4. **Cannot start with**: `@` (reserved) or digit **Valid examples:** - `schema` - Simple name - `v1.0` - Version with dot - `my-api_v2` - Hyphens and underscores - `_internal` - Starts with underscore (allowed) - `v1.` - Ends with dot (allowed) - `dc` - Short name **Invalid examples:** - `@custom` - Starts with `@` (reserved for system) - `1version` - Starts with digit - `-prefix` - Starts with hyphen - `bad:name` - Contains colon (reserved in XML) - `bad/name` - Contains slash - `bad name` - Contains space **Recommendations:** - Use descriptive names: `schema`, `company`, `api_v2` - Follow conventions: `dc` (Dublin Core), `foaf` (Friend of a Friend) - Version naming: `v1`, `v2`, `v1.0`, `api_v2` - Underscore prefixes for internal use: `_temp`, `_draft` - Avoid single letters: `x`, `y`, `z` (not self-documenting) {% callout type="note" %} Note that Turtle and SPARQL use a narrower specification. TerminusDB aligns with XML NCName for prefix names which is broader. Keep within the PN_PREFIX to avoid prefix surprises. TerminusDB stays XML-friendly where possible, and uses conventions from the XML world where it is reasonable. {% /callout %} ### IRI Format Rules All IRIs must include a valid scheme: **Valid:** - `http://example.org/` - `https://schema.org/` - `urn:isbn:` **Invalid:** - `example.org/` (missing scheme) - `www.example.org/` (missing scheme) - `//example.org/` (missing scheme) **Error example:** ```json { "@type": "api:PrefixErrorResponse", "api:status": "api:failure", "api:error": { "@type": "api:InvalidIRI", "api:iri": "example.org/" }, "api:message": "Invalid IRI: 'example.org/'. IRIs must have a valid scheme (e.g., http://, https://)" } ``` ### Reserved Prefixes (JSON-LD Keywords) **All prefixes starting with `@` are reserved for JSON-LD keywords and cannot be modified.** JSON-LD uses the `@` namespace for special keywords. TerminusDB blocks all `@`-prefixed names to maintain JSON-LD compliance. Common JSON-LD keywords include: | Prefix | Purpose | Can Modify? | |--------|---------|-------------| | `@base` | Base IRI for instance data | ❌ No | | `@schema` | Schema IRI | ❌ No | | `@type` | Type indicator in JSON-LD | ❌ No | | Any other `@*` | Reserved for future use | ❌ No | | All other names | User-defined | βœ… Yes | **Attempting to modify reserved prefixes:** ```json { "@type": "api:PrefixErrorResponse", "api:status": "api:failure", "api:error": { "@type": "api:ReservedPrefix", "api:prefix_name": "@base" }, "api:message": "Cannot modify reserved prefix '@base'. Prefixes starting with '@' are reserved." } ``` ### Unicode & Internationalization Prefix IRIs support full Unicode, including emoji and international characters: ```bash # Emoji in IRI (yes, this works!) curl -X POST http://localhost:6363/api/prefix/admin/mydb/rocket \ -u admin:root -H "Content-Type: application/json" \ -d '{"uri": "http://example.org/πŸš€/"}' # International characters curl -X POST http://localhost:6363/api/prefix/admin/mydb/cn \ -u admin:root -H "Content-Type: application/json" \ -d '{"uri": "http://example.org/δΈ­ζ–‡/"}' ``` ### Atomicity & Concurrency All operations are **ACID-compliant**: - **Atomic**: Operations succeed completely or not at all - **Consistent**: Database remains in valid state - **Isolated**: Concurrent operations don't interfere - **Durable**: Changes persist after successful response **Safe for concurrent use:** Multiple clients can add/update/delete prefixes simultaneously without data corruption. ## Additional Resources ### View All Prefixes Get the complete context document with all prefixes: ```bash curl -X GET http://localhost:6363/api/prefixes/admin/mydb -u admin:root ``` Returns `@base`, `@schema`, and all custom prefixes in a single JSON-LD context document. ### Client Libraries For programmatic access, use the TerminusDB client libraries: - **JavaScript**: `client.getPrefix()`, `client.addPrefix()`, etc. (coming soon) - **Python**: `client.get_prefix()`, `client.add_prefix()`, etc. (coming soon) ### Related Documentation - [JSON-LD Contexts](https://www.w3.org/TR/json-ld11/#the-context) - W3C standard - [Schema.org](https://schema.org/) - Common vocabulary for structured data - [Dublin Core](https://www.dublincore.org/) - Metadata vocabulary - [FOAF](http://xmlns.com/foaf/spec/) - Friend of a Friend vocabulary ## Troubleshooting ### Common Issues **Problem:** "Prefix already exists" when using POST - **Solution:** Use PUT to update, or DELETE then POST, or use PUT with `?create=true` for upsert **Problem:** "Invalid IRI" error - **Solution:** Ensure URI includes scheme (`http://`, `https://`, etc.) **Problem:** "Cannot modify reserved prefix" - **Solution:** Use a different prefix name (don't start with `@`) **Problem:** Changed prefix but documents still use old IRI - **Solution:** This is expected. Changing a prefix only affects future prefix expansion, not existing documents. Documents store full IRIs internally.