

# PIN Management

Create and delete custom PINs on igloohome locks.

---

## createPin

Creates a custom PIN on the lock via Bluetooth and registers it on the server. The SDK writes the PIN to lock hardware first, then registers on the server. If server registration fails, the SDK automatically deletes the PIN from the lock.

### Signature

```kotlin
suspend fun createPin(
    deviceId: String,
    key: String,
    pin: String,
    pinType: PinType,
    name: String,
    startTimeInSeconds: Long? = null,
    endTimeInSeconds: Long? = null,
    accessToken: String,
): CreatePinResponse
```

```swift
func createPin(
    deviceId: String,
    key: String,
    name: String,
    pin: String,
    pinType: PinType,
    startDate: Date?,
    endDate: Date?,
    accessToken token: String
) async throws
```

### Parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `deviceId` | `String` | Yes | Bluetooth device name of the lock. |
| `key` | `String` | Yes | eKey with `CREATE_PIN` permission. |
| `pin` | `String` | Yes | PIN code (numeric, 1–12 digits). |
| `pinType` | `PinType` | Yes | PIN type: `ONETIME`, `PERMANENT`, or `DURATION`. |
| `name` | `String` | Yes | User-assigned name for the PIN. |
| `startTimeInSeconds` | `Long?` | Duration only | Start time in epoch seconds. Required for `DURATION` type. |
| `endTimeInSeconds` | `Long?` | Duration only | End time in epoch seconds. Required for `DURATION` type. |
| `accessToken` | `String` | Yes | Access token for server calls. |

### Supporting Types

```kotlin
enum class PinType {
    ONETIME,
    PERMANENT,
    DURATION,
}
```

```swift
public enum PinType: String, Sendable {
    case otp = "otp"
    case permanent = "permanent"
    case duration = "duration"
}
```

### Return Type

```kotlin
data class CreatePinResponse(
    val accessId: String,
    val name: String,
    val pin: String,
    val pinType: String,
    val startDateTime: String?,
    val endDateTime: String?,
)
```

### Error Codes

| Exception | Code | Description |
|-----------|------|-------------|
| `BluetoothException` | 708 | Bluetooth is off or unavailable. |
| `ConnectionException` | 12 | Device disconnected during PIN creation. |
| `TimeoutException` | 703 | BLE operation exceeded the timeout. |
| `DuplicatePinException` | 880 | PIN already exists on the lock. |
| `LockStorageFullException` | 912 | No storage for more PINs on the lock. |
| `ApiException` | varies | Server registration failed (PIN rolled back from lock). |

### Example

```kotlin
try {
    val result = sdk.createPin(
        deviceId = "IGM401abc123",
        key = guestKey,
        pin = "123456",
        pinType = PinType.PERMANENT,
        name = "Front Door PIN",
        accessToken = accessToken,
    )
    println("PIN created: ${result.accessId}")
} catch (e: IglooHomeException.DuplicatePinException) {
    showError("This PIN already exists on the lock")
} catch (e: IglooHomeException.LockStorageFullException) {
    showError("Lock is full — delete a PIN first")
} catch (e: IglooHomeException) {
    showError("Failed: ${e.message}")
}
```

```swift
do {
    try await sdk.createPin(
        deviceId: "IGM401abc123",
        key: guestKey,
        name: "Front Door PIN",
        pin: "123456",
        pinType: .permanent,
        startDate: nil,
        endDate: nil,
        accessToken: accessToken)
    showSuccess(message: "PIN created")
} catch IgloohomeError.duplicatePin {
    showError(message: "This PIN already exists on the lock")
} catch IgloohomeError.lockStorageFull {
    showError(message: "Lock is full — delete a PIN first")
} catch {
    showError(message: "Failed: \(error.localizedDescription)")
}
```

---

## deletePin

Deletes a PIN from the lock and removes the server record.

The SDK fetches the PIN value from the server, removes it from lock hardware via BLE, then deletes the server record. If the PIN is already removed from the lock (BLE error 890), the SDK still deletes the server record.

### Signature

```kotlin
suspend fun deletePin(
    deviceId: String,
    key: String,
    accessId: String,
    accessToken: String,
)
```

```swift
func deletePin(
    deviceId: String,
    key: String,
    accessId: String,
    accessToken token: String
) async throws
```

### Parameters

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `deviceId` | `String` | Yes | Bluetooth device name of the lock. |
| `key` | `String` | Yes | eKey with `DELETE_PIN` permission. |
| `accessId` | `String` | Yes | Server-assigned access ID of the PIN to delete. |
| `accessToken` | `String` | Yes | Access token for server calls. |

### Error Codes

| Exception | Code | Description |
|-----------|------|-------------|
| `BluetoothException` | 708 | Bluetooth is off or unavailable. |
| `ConnectionException` | 12 | Device disconnected during deletion. |
| `TimeoutException` | 703 | BLE operation exceeded the timeout. |
| `ApiException` | varies | Server deletion failed. |

### Example

```kotlin
try {
    sdk.deletePin(
        deviceId = "IGM401abc123",
        key = guestKey,
        accessId = "access-123",
        accessToken = accessToken,
    )
    showSuccess("PIN deleted")
} catch (e: IglooHomeException.ConnectionException) {
    showError("unexpected bluetooth connection issue")
} catch (e: IglooHomeException.TimeoutException) {
    showError("Timed out, try again")
} catch (e: IglooHomeException) {
    showError("Failed: ${e.message}")
}
```

```swift
do {
    try await sdk.deletePin(
        deviceId: "IGM401abc123",
        key: guestKey,
        accessId: "access-123",
        accessToken: accessToken)
    showSuccess(message: "PIN deleted")
} catch {
    showError(message: "Failed: \(error.localizedDescription)")
}
```

### Notes

- Server deletion retries up to 3 times with 1-second delays on failure.
- `PinNotFoundException` (890, Android) / `IgloohomeError.pinNotFound` (iOS) during BLE delete is treated as non-fatal — the SDK continues to delete the server record.
