Use a custom domain


As part of our paid plans, you can configure a custom domain to work with a particular tenant to represent your brand and instil trust with end-users who will use a wallet to interact with the tenant to obtain or present credentials.

The MATTR VII trial account does not include ongoing access to Custom domains, the APIs are available if you wish to trial the feature, however it may be deactivated unless you are on a paid account.

The custom domain doesn’t change how you interact with your tenant for administration functions and doesn’t prevent the existing tenant domain from being accessed.

The model we have chosen for custom domains does not require full DNS mapping of a custom domain to a tenant (i.e. CNAME or A record) because the tenant is not exposed directly to end-users. Instead, we allow you to set a custom domain and then prove ownership using a TXT record on the DNS record. Once verified, the platform will default to using this custom domain when issuing and asserting DID-to-domain linkages.

  • web application manifest in the form of a manifest.json file will be made available at the root of your tenant. This will serve content, such as a logo, to clients in a standards-compatible way.

  • Update all DID configuration entries (which are DomainLinkageCredential credentials) to reference the custom domain.

    • This will ensure any wallet clients that resolve a DID from your domain and view the DID-to-Domain linkage.

  • Any Presentation Templates created will need to use the custom domain

The OIDC Bridge extension will default to using the custom domain when issuing credentials.

  • The OpenID Configuration endpoint will need to be made available on the custom domain, however all necessary OIDC endpoints remain as the tenant default domain, which is valid OIDC configuration.

There are some properties to consider when using a custom domain

  • A MATTR VII tenant can only have one custom domain.

  • Once configured the platform will default to exposing trust via that domain (e.g. DID configuration and Presentation Templates)


  • Only available on MATTR VII paid plans, get in touch to learn more.

  • You must have an existing domain or procure a new one from a domain registrar.

  • Have control over and able to update the DNS records for that domain.

  • You will need a separate web service that runs on that domain that can redirect or proxy requests.

You may choose to create a separate subdomain from your main web presence to expose to end-users as part of managing their digital identities, or you may choose to run from your existing main website. The choice may come down to practical implementation details as you will need to setup redirects to certain paths:

Copy to clipboard.

If these paths are already or likely to be used by your main website, you may want to consider using them under a subdomain.

Configure your domain on the tenant

In the config area of the API, use the Create a custom domain operation to initially set up the domain. The platform won’t immediately start using this custom domain until it is Verified.


Copy to clipboard.
1POST https://YOUR_TENANT_URL/core/v1/config/domain
Copy to clipboard.
2  "name": "Custom Site",
3  "logoUrl": "",
4  "domain": ""

Use a meaningful name that you want customers to know you by. The logoUrl should meet some minimum standards:

  • Must be a valid .png or .jpg

  • For best results on the wallet, we recommend a 65px square image

In the domain field add just the full domain (including subdomain) but do not include the protocol (https://).


Copy to clipboard.
2  "name": "Custom Site",
3  "logoUrl": "",
4  "domain": "",
5  "verificationToken": "a45ba33b-6c47-4349-7d49-a516c4d38406",
6  "isVerified": false

In the response, there are 2 additional fields: The verificationToken is the value required to be added to the TXT record in the DNS entry, isVerified will remain false until the domain has passed verification.

Verify domain ownership using DNS

By inserting the verificationToken into a TXT record in your DNS settings for the domain you control, you can prove ownership of the domain to the platform.

The exact steps to perform this will vary depending on your DNS service provider.

It’s common that another person or team will control access to the DNS records of your domain. Just ask them to add a text record for the domain name you require, using the value from your verificationToken e.g.

"Pease add a text record TXT to “” with a value of a45ba33b-6c47-4349-7d49-a516c4d38406 the TTL can be long, the TXT record will need to exist on the domain indefinitely while using the MATTR VII platform".

Example using GO Daddy

  1. Log in to your GoDaddy Domain Control Center.

  2. Select your domain to access the Domain Settings page.

  3. Under Additional Settings, select Manage DNS.

  4. Select ADD below the table of your existing DNS records.

  5. Choose TXT from the record options drop-down menu.

  6. Enter the details for your TXT record: Host: Enter the hostname for the TXT record. For example, type www to put the record on e.g. To put the host on, enter @ in the Host field.

  7. TXT Value: Add the verificationToken value e.g. a45ba33b-6c47-4349-7d49-a516c4d38406

  8. TTL: Determine how long the server should cache information - the value is unlikely to change and has no impact if it does, so the TTL could be several days

  9. Select Save to complete your updates.

It can take a few hours for the record to be available on the public DNS.

Example using Cloudflare

  1. Log in to your Cloudflare account

  2. Select your domain

  3. In the menu bar, select DNS

  4. In the DNS Records area, click the drop-down and select TXT

  5. Add an @ symbol in the Name

  6. In the ‘Click to configure’ field, click to open the dialogue and add your verificationToken value e.g. a45ba33b-6c47-4349-7d49-a516c4d38406

  7. Leave the TTL as ‘Automatic’

  8. Save to update

It can take a few hours for the record to be available on the public DNS.

Other example DNS providers

AWS using Route53, Google Domains using Workspace Admin, Entrust: Certificate services and, Akamai Edge DNS supported types

Verify your custom domain

Once your DNS provider has registered your TXT value and the change has been propagated, the platform will need to reach out to the public DNS record and confirm the value matches the one set up on your tenant.

To trigger this check, go to Verify custom domain:

Copy to clipboard.
1POST https://YOUR_TENANT_URL/core/v1/config/domain/verify

Response codes:

204 response (with no body) indicates that the verification was a success!

If you receive a 400 then something has gone wrong with the DNS setup, it could be that you need to wait longer to ensure your TXT record has propagated or try those steps again. A 404 would indicate you have not setup custom domains at all, start from the beginning of this guide.

Confirm your custom domain

Now when you call Retrieve custom domain:

Copy to clipboard.
1GET https://YOUR_TENANT_URL/core/v1/config/domain

You will see the isVerfied boolean is now true.


Copy to clipboard.
2  "name": "Custom Site",
3  "logoUrl": "",
4  "domain": "",
5  "verificationToken": "46077231-f7f4-4559-8405-6e875b81805f",
6  "isVerified": true,
7  "verifiedAt": "2021-05-21T04:02:48.638Z"

Using your custom domain

Now that the platform knows you control the domain, it will configure certain trust points including the DID to Domain linkage credentials served at /.well-known/did-configuration and the domain value used in secure DID messaging.

There are 4 static assets that require to be served as if from your custom domain, these are all served from the tenant:

There are 3 methods to achieve this:

  • Redirect traffic - using a 301 response with the URL of the tenant as the location the mobile wallet will fetch assets from the tenant.

  • Proxy traffic - your service will fetch the responses and serve the assets to the mobile wallet.

  • Host the assets - these assets are static so it is possible to host directly on a site with your domain, however, you will need to keep the assets in sync with any changes you make in your tenant.

The rest of the tutorial will focus on redirecting traffic to the tenant domain.


You can set up redirects for certain key paths that will direct traffic to the tenant on the MATTR VII platform.

There are currently 4 assets that require a redirect:

  1. For clients like the MATTR mobile wallet to view information about your custom domain, including the logo image and the name, you will need to redirect the manifest.json file.

  2. To obtain trust in the DID to domain linkages, then the ./well-known/did-configuration file must be referenced.

  3. To use a DID Web hosted on the domain, reference the ./well-known/did.json

  4. For credential issuance flows to work using the OpenID credential provisioning setup this /.well-known/openid-credential-issuer.

The first 2 assets are mandatory to use a custom domain, however, to use all functionality on the platform it’s recommended to redirect all 4 paths:

Copy to clipboard.
1/manifest.json                                         https://YOUR_TENANT_URL/manifest.json
2/.well-known/did-configuration                         https://YOUR_TENANT_URL/.well-known/did-configuration
3/.well-known/did.json                                  https://YOUR_TENANT_URL/.well-known/did.json
4/.well-known/openid-credential-issuer                  https://YOUR_TENANT_URL/.well-known/openid-credential-issuer

Alternatively, if you are using a dedicated subdomain then just redirect all traffic to the tenant url.

Copy to clipboard.

Try it out

The custom domain feature works alongside the existing capabilities of the platform. Custom domains are generally used for any outward-facing domains that the wallet would interact with, such as:

  • whenever a QR code is generated

  • whenever a domain is required as part of the setup

Issue a credential

Follow the Issue a credential using OpenID Credential Provisioning tutorial to setup your tenant to be able to issue credentials to the mobile wallet.

When generating a QR code, reference your custom domain as the issuer= value. e.g. using a QR generator service; 

The mobile wallet will read this value and perform some actions;

  1. Using the custom domain it will try to obtain the manifest.json

Your site will redirect to: https://YOUR_TENANT_URL/manifest.json

And your logoUrl and name can be obtained.

  1. Then it will obtain the OpenId Credential issuer metadata;

Your site will redirect to:


And your OpenId Credential issuer metadata will be obtained.

Verify a credential

Follow a tutorial on how to Verify a credential, either the Verify using a callback tutorial or Verify a credential using OIDC Bridge.

When setting up the Presentation Template you will need to use your custom domain as the domain value in the template.

As soon as your custom domain for a tenant is verified any previously configured templates will start to fail during the verification flow. You can use the Update presentation template operation to update.

Once this is configured, you can use this template ID in either verification flow. Since the interaction with the mobile wallet is handled by the platform, you should see these steps occurring:

  1. After the mobile wallet receives the signed JWM, it will first confirm that the domain used in the message has control over the DID used to sign the payload.

  2. The mobile wallet will fetch the and your site will redirect to: https://YOUR_TENANT_URL/.well-known/did-configuration

  3. For relevant interactions, the mobile wallet will confirm that there is a valid DomainLinkageCredential that matches the custom domain to the DID.

Example did-configuration response

Copy to clipboard.
2    "@context": [
3        "",
4        ""
5    ],
6    "type": [
7        "VerifiableCredential",
8        "DomainLinkageCredential"
9    ],
10    "issuer": "",
11    "issuanceDate": "2021-06-08T21:16:30.965Z",
12    "credentialSubject": {
13        "id": "did:key:z6Mki8prLixhy8VinFRSmYNq556tX8Bjw43KCZVnZPRG4ihn",
14        "origin": ""
15    },
16    "proof": {
17        "type": "Ed25519Signature2018",
18        "created": "2021-06-08T21:16:33Z",
19        "jws": "eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..LXiwjLCOx09RWziwsfEA1qRSEDk6MMrnv9AyLJbQPfzs629AImN37_0Pk414XUrgMrpvt1vwzoeHieQqk4WsBw",
20        "proofPurpose": "assertionMethod",
21        "verificationMethod": "did:key:z6Mki8prLixhy8VinFRSmYNq556tX8Bjw43KCZVnZPRG4ihn#z6Mki8prLixhy8VinFRSmYNq556tX8Bjw43KCZVnZPRG4ihn"
22    }

The reply_to URL in the message remains as the platform, the wallet will send this message to the platform and the verify flow can continue as normal.