# Stream metadata

Every stream in EventStoreDB has metadata stream associated with it, prefixed by $$, so the metadata stream from a stream called foo is $$foo. Internally, the metadata includes information such as the ACL of the stream, the maximum count and age for the events in the stream. Client code can also add information into stream metadata for use with projections or the client API.

Stream metadata is stored internally as JSON, and you can access it over the HTTP API.

# Reading stream metadata

To read the metadata, issue a GET request to the attached metadata resource, which is typically of the form:

http://{eventstore-ip-address}/streams/{stream-name}/metadata

You should not access metadata by constructing this URL yourself, as the right to change the resource address is reserved. Instead, you should follow the link from the stream itself, which enables your client to tolerate future changes to the addressing structure.

    curl -i -H "Accept:application/vnd.eventstore.atom+json" \
        http://127.0.0.1:2113/streams/%24users --user admin:changeit
    HTTP/1.1 200 OK
    Access-Control-Allow-Methods: POST, DELETE, GET, OPTIONS
    Access-Control-Allow-Headers: Content-Type, X-Requested-With, X-Forwarded-Host, X-Forwarded-Prefix, X-PINGOTHER, Authorization, ES-LongPoll, ES-ExpectedVersion, ES-EventId, ES-EventType, ES-RequiresMaster, ES-HardDelete, ES-ResolveLinkTos
    Access-Control-Allow-Origin: *
    Access-Control-Expose-Headers: Location, ES-Position, ES-CurrentVersion
    Cache-Control: max-age=0, no-cache, must-revalidate
    Vary: Accept
    ETag: "3;-2060438500"
    Content-Type: application/vnd.eventstore.atom+json; charset=utf-8
    Server: Mono-HTTPAPI/1.0
    Date: Thu, 23 Aug 2018 10:03:34 GMT
    Content-Length: 2670
    Keep-Alive: timeout=15,max=100
    
    {
      "title": "Event stream '$users'",
      "id": "http://127.0.0.1:2113/streams/%24users",
      "updated": "2018-08-23T09:19:37.880827Z",
      "streamId": "$users",
      "author": {
        "name": "EventStore"
      },
      "headOfStream": true,
      "selfUrl": "http://127.0.0.1:2113/streams/%24users",
      "eTag": "3;-2060438500",
      "links": [
        {
          "uri": "http://127.0.0.1:2113/streams/%24users",
          "relation": "self"
        },
        {
          "uri": "http://127.0.0.1:2113/streams/%24users/head/backward/20",
          "relation": "first"
        },
        {
          "uri": "http://127.0.0.1:2113/streams/%24users/4/forward/20",
          "relation": "previous"
        },
        {
          "uri": "http://127.0.0.1:2113/streams/%24users/metadata",
          "relation": "metadata"
        }
      ],
      "entries": [
        {
          "title": "3@$users",
          "id": "http://127.0.0.1:2113/streams/%24users/3",
          "updated": "2018-08-23T09:19:37.880827Z",
          "author": {
            "name": "EventStore"
          },
          "summary": "$User",
          "links": [
            {
              "uri": "http://127.0.0.1:2113/streams/%24users/3",
              "relation": "edit"
            },
            {
              "uri": "http://127.0.0.1:2113/streams/%24users/3",
              "relation": "alternate"
            }
          ]
        },
        {
          "title": "2@$users",
          "id": "http://127.0.0.1:2113/streams/%24users/2",
          "updated": "2018-08-23T09:08:40.499762Z",
          "author": {
            "name": "EventStore"
          },
          "summary": "$User",
          "links": [
            {
              "uri": "http://127.0.0.1:2113/streams/%24users/2",
              "relation": "edit"
            },
            {
              "uri": "http://127.0.0.1:2113/streams/%24users/2",
              "relation": "alternate"
            }
          ]
        },
        {
          "title": "1@$users",
          "id": "http://127.0.0.1:2113/streams/%24users/1",
          "updated": "2018-08-23T07:55:39.833203Z",
          "author": {
            "name": "EventStore"
          },
          "summary": "$User",
          "links": [
            {
              "uri": "http://127.0.0.1:2113/streams/%24users/1",
              "relation": "edit"
            },
            {
              "uri": "http://127.0.0.1:2113/streams/%24users/1",
              "relation": "alternate"
            }
          ]
        },
        {
          "title": "0@$users",
          "id": "http://127.0.0.1:2113/streams/%24users/0",
          "updated": "2018-08-23T07:55:39.829589Z",
          "author": {
            "name": "EventStore"
          },
          "summary": "$User",
          "links": [
            {
              "uri": "http://127.0.0.1:2113/streams/%24users/0",
              "relation": "edit"
            },
            {
              "uri": "http://127.0.0.1:2113/streams/%24users/0",
              "relation": "alternate"
            }
          ]
        }
      ]
    }
    // Make sure to add code blocks to your code group

    Once you have the URI of the metadata stream, issue a GET request to retrieve the metadata:

    curl -i -H "Accept:application/vnd.eventstore.atom+json" http://127.0.0.1:2113/streams/%24users/metadata --user admin:changeit
    

    If you have security enabled, reading metadata may require that you pass credentials, as in the examples above. If credentials are required and you do not pass them, then you receive a 401 Unauthorized response.

      curl -i -H "Accept:application/vnd.eventstore.atom+json" http://127.0.0.1:2113/streams/%24users
      HTTP/1.1 401 Unauthorized
      Access-Control-Allow-Methods: GET, POST, GET, OPTIONS
      Access-Control-Allow-Headers: Content-Type, X-Requested-With, X-Forwarded-Host, X-Forwarded-Prefix, X-PINGOTHER, Authorization, ES-LongPoll, ES-ExpectedVersion, ES-EventId, ES-EventType, ES-RequiresMaster, ES-HardDelete, ES-ResolveLinkTos
      Access-Control-Allow-Origin: *
      Access-Control-Expose-Headers: Location, ES-Position, ES-CurrentVersion
      WWW-Authenticate: Basic realm="ES"
      Content-Type: text/plain; charset=utf-8
      Server: Mono-HTTPAPI/1.0
      Date: Thu, 23 Aug 2018 10:26:52 GMT
      Content-Length: 0
      Keep-Alive: timeout=15,max=100
      // Make sure to add code blocks to your code group

      # Writing metadata

      To update the metadata for a stream, issue a POST request to the metadata resource.

      Inside a file named metadata.json:

      [
          {
              "eventId": "7c314750-05e1-439f-b2eb-f5b0e019be72",
              "eventType": "$user-updated",
              "data": {
                  "readRole": "$all",
                  "metaReadRole": "$all"
              }
          }
      ]

      You can also add user-specified metadata here. Some examples user-specified metadata are:

      • Which adapter populates a stream.
      • Which projection created a stream.
      • A correlation ID to a business process.

      You then post this information is then posted to the stream:

        curl -i -d @metadata.json http://127.0.0.1:2113/streams/%24users/metadata \
            --user admin:changeit \
            -H "Content-Type: application/vnd.eventstore.events+json"
        HTTP/1.1 201 Created
        Access-Control-Allow-Methods: GET, POST, GET, OPTIONS
        Access-Control-Allow-Headers: Content-Type, X-Requested-With, X-Forwarded-Host, X-Forwarded-Prefix, X-PINGOTHER, Authorization, ES-LongPoll, ES-ExpectedVersion, ES-EventId, ES-EventType, ES-RequiresMaster, ES-HardDelete, ES-ResolveLinkTos
        Access-Control-Allow-Origin: *
        Access-Control-Expose-Headers: Location, ES-Position, ES-CurrentVersion
        Location: http://127.0.0.1:2113/streams/%24%24%24users/0
        Content-Type: text/plain; charset=utf-8
        Server: Mono-HTTPAPI/1.0
        Date: Thu, 23 Aug 2018 10:35:19 GMT
        Content-Length: 0
        Keep-Alive: timeout=15,max=100
        // Make sure to add code blocks to your code group

        If the specified user does not have permissions to write to the stream metadata, you receive a '401 Unauthorized' response.

        Last Updated: 1/1/2021, 11:29:55 AM