

# SPARQL HTTP API
<a name="sparql-api-reference"></a>

SPARQL HTTP requests are accepted at the following endpoint: `https://your-neptune-endpoint:port/sparql`

For more information about connecting to Amazon Neptune with SPARQL, see [Accessing the Neptune graph with SPARQL](access-graph-sparql.md).

For more information about the SPARQL protocol and query language, see the [SPARQL 1.1 Protocol](https://www.w3.org/TR/sparql11-protocol/#protocol) and the [SPARQL 1.1 Query Language](https://www.w3.org/TR/sparql11-query/) specification.

The following topics provide information about SPARQL RDF serialization formats and how to use the SPARQL HTTP API with Neptune.

**Contents**
+ [Using the HTTP REST endpoint to connect to a Neptune DB instance](access-graph-sparql-http-rest.md)
+ [Optional HTTP trailing headers for multi-part SPARQL responses](access-graph-sparql-http-trailing-headers.md)
+ [RDF media types used by SPARQL in Neptune](sparql-media-type-support.md)
  + [RDF serialization formats used by Neptune SPARQL](sparql-media-type-support.md#sparql-serialization-formats)
  + [SPARQL result serialization formats used by Neptune SPARQL](sparql-media-type-support.md#sparql-serialization-formats-neptune-output)
  + [Media-Types that Neptune can use to import RDF data](sparql-media-type-support.md#sparql-serialization-formats-input)
  + [Media-Types that Neptune can use to export query results](sparql-media-type-support.md#sparql-serialization-formats-output)
+ [Using SPARQL UPDATE LOAD to import data into Neptune](sparql-api-reference-update-load.md)
+ [Using SPARQL UPDATE UNLOAD to delete data from Neptune](sparql-api-reference-unload.md)

# Using the HTTP REST endpoint to connect to a Neptune DB instance
<a name="access-graph-sparql-http-rest"></a>

**Note**  
Neptune does not currently support HTTP/2 for REST API requests. Clients must use HTTP/1.1 when connecting to endpoints.

The following instructions walk you through connecting to the SPARQL endpoint using the **curl** command, connecting through HTTPS, and using HTTP syntax. Follow these instructions from an Amazon EC2 instance in the same virtual private cloud (VPC) as your Neptune DB instance.

The HTTP endpoint for SPARQL queries to a Neptune DB instance is:  `https://your-neptune-endpoint:port/sparql`.

**Note**  
For information about finding the hostname of your Neptune DB instance, see the [Connecting to Amazon Neptune Endpoints](feature-overview-endpoints.md) section.

Amazon Neptune provides an HTTP endpoint for SPARQL queries. The REST interface is compatible with SPARQL version 1.1.

**QUERY Using HTTP POST**  
The following example uses **curl** to submit a SPARQL **`QUERY`** through HTTP **POST**.

```
curl -X POST --data-binary 'query=select ?s ?p ?o where {?s ?p ?o} limit 10' https://your-neptune-endpoint:port/sparql
```

The preceding example returns up to 10 of the triples (subject-predicate-object) in the graph by using the `?s ?p ?o` query with a limit of 10. To query for something else, replace it with another SPARQL query.

**Note**  
The default MIME media type of a response is `application/sparql-results+json` for `SELECT` and `ASK` queries.  
The default MIME type of a response is `application/n-quads` for `CONSTRUCT` and `DESCRIBE` queries.  
For a list of the media types used by Neptune for serialization, see [RDF serialization formats used by Neptune SPARQL](sparql-media-type-support.md#sparql-serialization-formats).

**UPDATE Using HTTP POST**  
The following example uses **curl** to submit a SPARQL **`UPDATE`** through HTTP **POST**.

```
curl -X POST --data-binary 'update=INSERT DATA { <https://test.com/s> <https://test.com/p> <https://test.com/o> . }' https://your-neptune-endpoint:port/sparql
```

The preceding example inserts the following triple into the SPARQL default graph: `<https://test.com/s> <https://test.com/p> <https://test.com/o>`

# Optional HTTP trailing headers for multi-part SPARQL responses
<a name="access-graph-sparql-http-trailing-headers"></a>

The HTTP response to SPARQL queries and updates is often returned in more than one part or chunk. It can be hard to diagnose a failure that occurs after a query or update begins sending these chunks, especially since the first one arrives with an HTTP status code of `200`.

Unless you explicitly request trailing headers, Neptune only reports such a failure by appending an error message to the message body, which is usually corrupted.

To make detection and diagnosis of this kind of problem easier, you can include a transfer-encoding (TE) trailers header (`te: trailers`) in your request (see, for example, [the MDN page about TE request headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/TE)). Doing this will cause Neptune to include two new header fields within the trailing headers of the response chunks:
+ `X-Neptune-Status`  –   contains the response code followed by a short name. For instance, in case of success the trailing header would be: `X-Neptune-Status: 200 OK`. In the case of failure, the response code would be an [Neptune engine error code](errors-engine-codes.md) such as `X-Neptune-Status: 500 TimeLimitExceededException`.
+ `X-Neptune-Detail`  –   is empty for successful requests. In the case of errors, it contains the JSON error message. Because only ASCII characters are allowed in HTTP header values, the JSON string is URL encoded. The error message is also still appended to the response message body.

# RDF media types used by SPARQL in Neptune
<a name="sparql-media-type-support"></a>

Resource Description Framework (RDF) data can be serialized in many different ways, most of which SPARQL can consume or output:

## RDF serialization formats used by Neptune SPARQL
<a name="sparql-serialization-formats"></a>
+ **RDF/XML**  –   XML serialization of RDF, defined in [RDF 1.1 XML Syntax](https://www.w3.org/TR/rdf-syntax-grammar/). Media type: `application/rdf+xml`. Typical file extension: `.rdf`.
+ **N-Triples**  –   A line-based, plain-text format for encoding an RDF graph, defined in [RDF 1.1 N-Triples](https://www.w3.org/TR/n-triples/). Media type: `application/n-triples`, `text/turtle`, or `text/plain`. Typical file extension: `.nt`.
+ **N-Quads**  –   A line-based, plain-text format for encoding an RDF graph, defined in [RDF 1.1 N-Quads](https://www.w3.org/TR/n-quads/). It is an extension of N-Triples. Media type: `application/n-quads`, or `text/x-nquads` when encoded with 7-bit US-ASCII. Typical file extension: `.nq`.
+ **Turtle**  –   A textual syntax for RDF defined in [ RDF 1.1 Turtle](https://www.w3.org/TR/turtle/) that allows an RDF graph to be completely written in a compact and natural text form, with abbreviations for common usage patterns and datatypes. Turtle provides levels of compatibility with the N-Triples format as well as SPARQL's triple pattern syntax. Media type: `text/turtle`Typical file extension: `.ttl`.
+ **TriG**  –   A textual syntax for RDF defined in [ RDF 1.1 TriG](https://www.w3.org/TR/trig/) that allows an RDF graph to be completely written in a compact and natural text form, with abbreviations for common usage patterns and datatypes. TriG is an extension of the Turtle format. Media type: `application/trig`. Typical file extension: `.trig`.
+ **N3 (Notation3)**  –   An assertion and logic language defined in [Notation3 (N3): A readable RDF syntax](https://www.w3.org/TeamSubmission/n3/). N3 extends the RDF data model by adding formulae (literals which are graphs themselves), variables, logical implication, and functional predicates, and provides a textual syntax alternative to RDF/XML. Media type: `text/n3`. Typical file extension: `.n3`.
+ **JSON-LD**  –   A data serialization and messaging format defined in [JSON-LD 1.0](https://www.w3.org/TR/json-ld/).Media type: `application/ld+json`. Typical file extension: `.jsonld`.
+ **TriX**  –   A serialization of RDF in XML, defined in [TriX: RDF Triples in XML](https://www.hpl.hp.com/techreports/2004/HPL-2004-56.html). Media type: `application/trix`. Typical file extension: `.trix`.
+ **SPARQL JSON Results**  –   A serialization of RDF using the [SPARQL 1.1 Query Results JSON Format](https://www.w3.org/TR/sparql11-results-json). Media type: `application/sparql-results+json`. Typical file extension: `.srj`.
+ **RDF4J Binary Format**  –   A binary format for encoding RDF data, documented in [RDF4J Binary RDF Format](https://rdf4j.org/documentation/reference/rdf4j-binary). Media type: `application/x-binary-rdf`.

## SPARQL result serialization formats used by Neptune SPARQL
<a name="sparql-serialization-formats-neptune-output"></a>
+ **SPARQL XML Results**  –   An XML format for the variable binding and boolean results formats provided by the SPARQL query language, defined in [SPARQL Query Results XML Format (Second Edition)](https://www.w3.org/TR/rdf-sparql-XMLres/). Media type: `application/sparql-results+xml`. Typical file extension: `.srx`.
+ **SPARQL CSV and TSV Results**  –   The use of comma-separated values and tab-separated values to express SPARQL query results from `SELECT` queries, defined in [SPARQL 1.1 Query Results CSV and TSV Formats](https://www.w3.org/TR/sparql11-results-csv-tsv/). Media type: `text/csv` for comma-separated values, and `text/tab-separated-values` for tab-separated values. Typical file extensions: `.csv` for comma-separated values, and `.tsv` for tab-separated values.
+ **Binary Results Table**  –   A binary format for encoding the output of SPARQL queries. Media type: `application/x-binary-rdf-results-table`.
+ **SPARQL JSON Results**  –   A serialization of RDF using the [SPARQL 1.1 Query Results JSON Format](https://www.w3.org/TR/sparql11-results-json/). Media type: `application/sparql-results+json`.

## Media-Types that Neptune can use to import RDF data
<a name="sparql-serialization-formats-input"></a>

**Media-types supported by the [Neptune bulk-loader](bulk-load.md)**
+ [N-Triples](https://www.w3.org/TR/n-triples/)
+ [N-Quads](https://www.w3.org/TR/n-quads/)
+ [RDF/XML](https://www.w3.org/TR/rdf-syntax-grammar/)
+ [Turtle](https://www.w3.org/TR/turtle/)

**Media-types that SPARQL UPDATE LOAD can import**
+ [N-Triples](https://www.w3.org/TR/n-triples/)
+ [N-Quads](https://www.w3.org/TR/n-quads/)
+ [RDF/XML](https://www.w3.org/TR/rdf-syntax-grammar/)
+ [Turtle](https://www.w3.org/TR/turtle/)
+ [TriG](https://www.w3.org/TR/trig/)
+ [N3](https://www.w3.org/TeamSubmission/n3/)
+ [JSON-LD](https://www.w3.org/TR/json-ld/)

## Media-Types that Neptune can use to export query results
<a name="sparql-serialization-formats-output"></a>

To specify the output format for a SPARQL query response, send an `"Accept: media-type"` header with the query request. For example:

```
curl -H "Accept: application/nquads" ...
```

**RDF media-types that SPARQL SELECT can output from Neptune**
+ [SPARQL JSON Results](https://www.w3.org/TR/sparql11-results-json) (This is the default)
+ [SPARQL XML Results](https://www.w3.org/TR/rdf-sparql-XMLres/)
+ **Binary Results Table** (media type: `application/x-binary-rdf-results-table`)
+ [Comma-Separated Values (CSV)](https://www.w3.org/TR/sparql11-results-csv-tsv/)
+ [Tab-Separated Values (TSV)](https://www.w3.org/TR/sparql11-results-csv-tsv/)

**RDF media-types that SPARQL ASK can output from Neptune**
+ [SPARQL JSON Results](https://www.w3.org/TR/sparql11-results-json) (This is the default)
+ [SPARQL XML Results](https://www.w3.org/TR/rdf-sparql-XMLres/)
+ **Boolean** (media type: `text/boolean`, meaning "true" or "false")

**RDF media-types that SPARQL CONSTRUCT can output from Neptune**
+ [N-Quads](https://www.w3.org/TR/n-quads/) (This is the default)
+ [RDF/XML](https://www.w3.org/TR/rdf-syntax-grammar/)
+ [JSON-LD](https://www.w3.org/TR/json-ld/)
+ [N-Triples](https://www.w3.org/TR/n-triples/)
+ [Turtle](https://www.w3.org/TR/turtle/)
+ [N3](https://www.w3.org/TeamSubmission/n3/)
+ [TriX](https://www.hpl.hp.com/techreports/2004/HPL-2004-56.html)
+ [TriG](https://www.w3.org/TR/trig/)
+ [SPARQL JSON Results](https://www.w3.org/TR/sparql11-results-json)
+ [RDF4J Binary RDF Format](https://rdf4j.org/documentation/reference/rdf4j-binary)

**RDF media-types that SPARQL DESCRIBE can output from Neptune**
+ [N-Quads](https://www.w3.org/TR/n-quads/) (This is the default)
+ [RDF/XML](https://www.w3.org/TR/rdf-syntax-grammar/)
+ [JSON-LD](https://www.w3.org/TR/json-ld/)
+ [N-Triples](https://www.w3.org/TR/n-triples/)
+ [Turtle](https://www.w3.org/TR/turtle/)
+ [N3](https://www.w3.org/TeamSubmission/n3/)
+ [TriX](https://www.hpl.hp.com/techreports/2004/HPL-2004-56.html)
+ [TriG](https://www.w3.org/TR/trig/)
+ [SPARQL JSON Results](https://www.w3.org/TR/sparql11-results-json)
+ [RDF4J Binary RDF Format](https://rdf4j.org/documentation/reference/rdf4j-binary)

# Using SPARQL UPDATE LOAD to import data into Neptune
<a name="sparql-api-reference-update-load"></a>

The syntax of the SPARQL UPDATE LOAD command is specified in the [SPARQL 1.1 Update recommendation](https://www.w3.org/TR/sparql11-update/#load):

```
LOAD SILENT (URL of data to be loaded) INTO GRAPH (named graph into which to load the data)
```
+ **`SILENT`**   –   (*Optional*) Causes the operation to return success even if there was an error during processing.

  This can be useful when a single transaction contains multiple statements like `"LOAD ...; LOAD ...; UNLOAD ...; LOAD ...;"` and you want the transaction to complete even if some of the remote data could not be processed.
+ *URL of data to be loaded*   –   (*Required*) Specifies a remote data file containing data to be loaded into a graph.

  The remote file must have one of the following extensions:
  + `.nt` for NTriples.
  + `.nq` for NQuads.
  + `.trig` for Trig.
  + `.rdf` for RDF/XML.
  + `.ttl` for Turtle.
  + `.n3` for N3.
  + `.jsonld` for JSON-LD.
+ **`INTO GRAPH`***(named graph into which to load the data)*   –   (*Optional*) Specifies the graph into which the data should be loaded.

  Neptune associates every triple with a named graph. You can specify the default named graph using the fallback named-graph URI, `http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph`, like this:

  ```
  INTO GRAPH <http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph>
  ```

**Note**  
When you need to load a lot of data, we recommend that you use the Neptune bulk loader rather than UPDATE LOAD. For more information about the bulk loader, see [Using the Amazon Neptune bulk loader to ingest data](bulk-load.md).

You can use `SPARQL UPDATE LOAD` to load data directly from Amazon S3, or from files obtained from a self-hosted web server. The resources to be loaded must reside in the same region as the Neptune server, and the endpoint for the resources must be allowed in the VPC. For information about creating an Amazon S3 endpoint, see [Creating an Amazon S3 VPC Endpoint](bulk-load-data.md#bulk-load-prereqs-s3).

All `SPARQL UPDATE LOAD` URIs must start with `https://`. This includes Amazon S3 URLs.

In contrast to the Neptune bulk loader, a call to `SPARQL UPDATE LOAD` is fully transactional.

**Loading files directly from Amazon S3 into Neptune using SPARQL UPDATE LOAD**

Because Neptune does not allow you to pass an IAM role to Amazon S3 when using SPARQL UPDATE LOAD, either the Amazon S3 bucket in question must be public or you must use a [pre-signed Amazon S3 URL](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html) in the LOAD query.

To generate a pre-signed URL for an Amazon S3 file, you can use an AWS CLI command like this:

```
aws s3 presign --expires-in (number of seconds) s3://(bucket name)/(path to file of data to load)
```

Then you can use the resulting pre-signed URL in your `LOAD` command:

```
curl https://(a Neptune endpoint URL):8182/sparql \
  --data-urlencode 'update=load (pre-signed URL of the remote Amazon S3 file of data to be loaded) \
                           into graph (named graph)'
```

For more information, see [Authenticating Requests: Using Query Parameters](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html). The [Boto3 documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/s3-presigned-urls.html) shows how to use a Python script to generate a presigned URL.

Also, the content type of the files to be loaded must be set correctly.

1. Set the content type of files when you upload them into Amazon S3 by using the `-metadata` parameter, like this:

   ```
   aws s3 cp test.nt s3://bucket-name/my-plain-text-input/test.nt --metadata Content-Type=text/plain
   aws s3 cp test.rdf s3://bucket-name/my-rdf-input/test.rdf --metadata Content-Type=application/rdf+xml
   ```

1. Confirm that the media-type information is actually present. Run:

   ```
   curl -v bucket-name/folder-name
   ```

   The output of this command should show the media-type information that you set when uploading the files.

1. Then you can use the `SPARQL UPDATE LOAD` command to import these files into Neptune:

   ```
   curl https://your-neptune-endpoint:port/sparql \
     -d "update=LOAD <https://s3.amazonaws.com/bucket-name/my-rdf-input/test.rdf>"
   ```

The steps above work only for a public Amazon S3 bucket, or for a bucket that you access using a [pre-signed Amazon S3 URL](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html) in the LOAD query.

 You can also set up a web proxy server to load from a private Amazon S3 bucket, as shown below:

**Using a web server to load files into Neptune with SPARQL UPDATE LOAD**

1. Install a web server on a machine running within the VPC that is hosting Neptune and the files to be loaded. For example, using Amazon Linux, you might install Apache as follows:

   ```
   sudo yum install httpd mod_ssl
   sudo /usr/sbin/apachectl start
   ```

1. Define the MIME type(s) of the RDF file-content that you are going to load. SPARQL uses the `Content-type` header sent by the web server to determine the input format of the content, so you must define the relevant MIME types for the web Server.

   For example, suppose you use the following file extensions to identify file formats:
   + `.nt` for NTriples.
   + `.nq` for NQuads.
   + `.trig` for Trig.
   + `.rdf` for RDF/XML.
   + `.ttl` for Turtle.
   + `.n3` for N3.
   + `.jsonld` for JSON-LD.

   If you are using Apache 2 as the web server, you would edit the file `/etc/mime.types` and add the following types:

   ```
    text/plain nt
    application/n-quads nq
    application/trig trig
    application/rdf+xml rdf
    application/x-turtle ttl
    text/rdf+n3 n3
    application/ld+json jsonld
   ```

1. Confirm that the MIME-type mapping works. Once you have your web server up and running and hosting RDF files in the format(s) of your choice, you can test the configuration by sending a request to the web server from your local host.

   For instance, you might send a request such as this:

   ```
   curl -v http://localhost:80/test.rdf
   ```

   Then, in the detailed output from `curl`, you should see a line such as:

   ```
   Content-Type: application/rdf+xml
   ```

   This shows that the content-type mapping was defined successfully.

1. You are now ready to load data using the SPARQL UPDATE command:

   ```
   curl https://your-neptune-endpoint:port/sparql \
       -d "update=LOAD <http://web_server_private_ip:80/test.rdf>"
   ```

**Note**  
Using `SPARQL UPDATE LOAD` can trigger a timeout on the web server when the source file being loaded is large. Neptune processes the file data as it is streamed in, and for a big file that can take longer than the timeout configured on the server. This in turn may cause the server to close the connection, which can result in the following error message when Neptune encounters an unexpected EOF in the stream:  

```
{
  "detailedMessage":"Invalid syntax in the specified file",
  "code":"InvalidParameterException"
}
```
If you receive this message and don't believe your source file contains invalid syntax, try increasing the timeout settings on the web server. You can also diagnose the problem by enabling debug logs on the server and looking for timeouts.

# Using SPARQL UPDATE UNLOAD to delete data from Neptune
<a name="sparql-api-reference-unload"></a>

Neptune also provides a custom SPARQL operation, `UNLOAD`, for removing data that is specified in a remote source. `UNLOAD` can be regarded as a counterpart to the `LOAD` operation. Its syntax is:

```
UNLOAD SILENT (URL of the remote data to be unloaded) FROM GRAPH (named graph from which to remove the data)
```
+ **`SILENT`**   –   (*Optional*) Causes the operation to return success even if there was an error when processing the data.

  This can be useful when a single transaction contains multiple statements like `"LOAD ...; LOAD ...; UNLOAD ...; LOAD ...;"` and you want the transaction to complete even if some of the remote data could not be processed.
+ *URL of the remote data to be unloaded*   –   (*Required*) Specifies a remote data file containing data to be unloaded from a graph.

  The remote file must have one of the following extensions (these are the same formats that UPDATE-LOAD supports):
  + `.nt` for NTriples.
  + `.nq` for NQuads.
  + `.trig` for Trig.
  + `.rdf` for RDF/XML.
  + `.ttl` for Turtle.
  + `.n3` for N3.
  + `.jsonld` for JSON-LD.

  All the data that this file contains will be removed from your DB cluster by the `UNLOAD` operation.

  Any Amazon S3 authentication must be included in the URL for the data to unload. You can pre-sign an Amazon S3 file and then use the resulting URL to access it securely. For example:

  ```
  aws s3 presign --expires-in (number of seconds) s3://(bucket name)/(path to file of data to unload)
  ```

  Then:

  ```
  curl https://(a Neptune endpoint URL):8182/sparql \
    --data-urlencode 'update=unload (pre-signed URL of the remote Amazon S3 data to be unloaded) \
                             from graph (named graph)'
  ```

  For more information, see [Authenticating Requests: Using Query Parameters](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html).
+ **`FROM GRAPH `***(named graph from which to remove the data)*   –   (*Optional*) Specifies the named graph from which the remote data should be unloaded.

  Neptune associates every triple with a named graph. You can specify the default named graph using the fallback named-graph URI, `http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph`, like this:

  ```
  FROM GRAPH <http://aws.amazon.com/neptune/vocab/v01/DefaultNamedGraph>
  ```

In the same way that `LOAD` corresponds to `INSERT DATA { (inline data) }`, `UNLOAD` corresponds to `DELETE DATA { (inline data) }`. Like `DELETE DATA`, `UNLOAD` does not work on data that contains blank nodes.

For example, if a local web server serves a file named `data.nt` that contains the following 2 triples:

```
<http://example.org/resource#a> <http://example.org/resource#p> <http://example.org/resource#b> .
<http://example.org/resource#a> <http://example.org/resource#p> <http://example.org/resource#c> .
```

The following `UNLOAD` command would delete those two triples from the named graph, `<http://example.org/graph1>`:

```
UNLOAD <http://localhost:80/data.nt> FROM GRAPH <http://example.org/graph1>
```

This would have the same effect as using the following `DELETE DATA` command:

```
DELETE DATA {
  GRAPH <http://example.org/graph1> {
    <http://example.org/resource#a> <http://example.org/resource#p> <http://example.org/resource#b> .
    <http://example.org/resource#a> <http://example.org/resource#p> <http://example.org/resource#c> .
  }
}
```

**Exceptions thrown by the `UNLOAD` command**
+ **`InvalidParameterException`**   –   There were blank nodes in the data. *HTTP status*: 400 Bad Request.

  *Message*: ` Blank nodes are not allowed for UNLOAD`

   
+ **`InvalidParameterException`**   –   There was broken syntax in the data. *HTTP status*: 400 Bad Request.

  *Message*: `Invalid syntax in the specified file.`

   
+ **`UnloadUrlAccessDeniedException `**   –   Access was denied. *HTTP status*: 400 Bad Request.

  *Message*: `Update failure: Endpoint (Neptune endpoint) reported access denied error. Please verify access.`

   
+ **`BadRequestException `**   –   The remote data cannot be retrieved. *HTTP status*: 400 Bad Request.

  *Message*: *(depends on the HTTP response).*