# Complete Registration

To complete registration you'll need the same header values as used in [initiate-registration](https://docs.0xpass.io/authentication/passkeys/registration/register-using-api/initiate-registration "mention"). The completeRegistration method is the part of the authentication API that finalizes the user registration process. It takes encrypted user data and a registration challenge, verifies it, and if successful, returns an identifier for the user.

### **Request Spec**

**HTTP Method**: POST

* [Headers](https://docs.0xpass.io/appendix/api-request-setup/unauthenticated-requests)
  * x-scope-id: A UUID string representing the application scope.
  * x-encrypted-key: A string containing the encrypted key for secure communication.
* **Body**:

  * encrypted\_attestation: A string containing the encrypted attestation object.

  The [initiate-registration](https://docs.0xpass.io/authentication/passkeys/registration/register-using-api/initiate-registration "mention") flow returns an `encrypted_creation_challenge`  which we need to decrypt with the decryption method below, and then, create an attestation, which we then encrypt and send as part of our request.

<pre class="language-typescript"><code class="lang-typescript">const cryptoObj = typeof window !== "undefined" ? window.crypto : crypto;

<strong>const decrypt = async (algo, key, data) => {
</strong>  try {
    const decryptedResult = await cryptoObj.subtle.decrypt(algo, key, data);
    return decryptedResult;
  } catch (error) {
    console.error("Decryption error:", error);
    throw error;
  }
};

const aesDecrypt = async (
  cipherText: string,
  encryptionKey: BufferSource,
  keyFormat: "raw" = "raw",
  keyLength: number = 256
) => {
  if (!encryptionKey) {
    throw Error("Encryption key not initialized");
  }
  let cryptoKey: CryptoKey;
  let decryptedData: ArrayBuffer;

  try {
    const combined = Uint8Array.from(atob(cipherText), (c) => c.charCodeAt(0));
    const iv = combined.slice(0, 12);
    const encryptedData = combined.slice(12);

    cryptoKey = await importKey(keyFormat, encryptionKey, { name: "AES-GCM", length: keyLength }, [
      "decrypt",
    ]);

    decryptedData = await decrypt({ name: "AES-GCM", iv }, cryptoKey, encryptedData);

    const decoder = new TextDecoder();
    return decoder.decode(new Uint8Array(decryptedData));
  } catch (error) {
    console.error("AES-GCM Decryption error:", error);
    throw error;
  }
};
</code></pre>

```typescript
const challenge_id = initRegResponse.result.challenge_id;
const credential_creation_opts = await aesDecrypt(
      initRegResponse.result.encrypted_creation_challenge,
      aesKeyt
 );
const cco_json = JSON.parse(cco_str);

// Once you have the credential creation options you can create a webauthn compatible 
// attestation / signature e.g by using the broswer navigator.credentials.create
// function

const attestation = navigator.credentials.create(cco_json);
```

You can then encrypt the attestation with your AES Key and send it as part of the request&#x20;

```typescript
const encrypted_attestation = await aesEncrypt(JSON.stringify(attestation), aesKey);
```

* encrypted\_user: A string containing the encrypted user data. This is the same encrypted\_user from [initiate-registration](https://docs.0xpass.io/authentication/passkeys/registration/register-using-api/initiate-registration "mention")
* challenge\_id: A UUID string representing the challenge issued during initiation. This is the challenge\_id result  from [initiate-registration](https://docs.0xpass.io/authentication/passkeys/registration/register-using-api/initiate-registration "mention")

### **Response Spec**

* **Success**:
  * account\_id: A UUID string that uniquely identifies the user's account.
  * identifier\_hash: A string representing the hash of the user's identifier.
* **Error**: An object containing error details.

### **Request Example**

```http
POST / HTTP/1.1
Host: tiramisu.0xpass.io
Content-Type: application/json
x-scope-id: 123e4567-e89b-12d3-a456-426614174000
x-encrypted-key: jp6...yKg==

{
  "jsonrpc": "2.0",
  "method": "completeRegistration",
  "params": {
    "encrypted_attestation": "JZV...Ug==",
    "encrypted_user": "JZV...Ug==",
    "challenge_id": "765e4567-e89b-12d3-a456-426614174000"
  },
  "id": 1
}
```

### **Response Example**

```http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "jsonrpc": "2.0",
  "result": {
    "account_id": "456e4567-e89b-12d3-a456-426614174000",
    "identifier_hash": "0x25e...1617"
  },
  "id": 1
}
```
