{
  "openapi": "3.0.4",
  "info": {
    "title": "Whrami Location Sharing API",
    "description": "Privacy-first location sharing API. Allows AI agents and automation tools to send locations, manage contacts, and coordinate meetups. No personal information required - just anonymous user IDs.",
    "contact": {
      "name": "Whrami Support",
      "url": "https://github.com/ozoid/whrami"
    },
    "version": "v1"
  },
  "paths": {
    "/api/Contacts/GetContactRequests": {
      "get": {
        "tags": [
          "Contacts"
        ],
        "summary": "Retrieves all pending contact/follow requests for a user.",
        "responses": {
          "200": {
            "description": "Returns list of contact requests (may be empty)",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ContactRequestDto"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ContactRequestDto"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ContactRequestDto"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Contacts/MarkContactRequestSeen": {
      "post": {
        "tags": [
          "Contacts"
        ],
        "parameters": [
          {
            "name": "requestId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Contacts/SendContactRequest": {
      "post": {
        "tags": [
          "Contacts"
        ],
        "summary": "Sends a contact/follow request to another user.",
        "description": "Sample request:\n\n    POST /api/Contacts/SendContactRequest\n    Headers:\n      X-User-Id: user123\n      X-Registration-Key: abc-def-ghi\n    Body:\n    {\n      \"toUserId\": \"user456\",\n      \"message\": \"Let's connect!\"\n    }",
        "requestBody": {
          "description": "Contact request with toUserId",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactRequestDto"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactRequestDto"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ContactRequestDto"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact request sent successfully"
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request data",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Contacts/DeclineContactRequest": {
      "post": {
        "tags": [
          "Contacts"
        ],
        "summary": "Declines a contact/follow request.",
        "requestBody": {
          "description": "The unique identifier of the request to decline",
          "content": {
            "application/json": {
              "schema": {
                "type": "integer",
                "format": "int32"
              }
            },
            "text/json": {
              "schema": {
                "type": "integer",
                "format": "int32"
              }
            },
            "application/*+json": {
              "schema": {
                "type": "integer",
                "format": "int32"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request declined successfully"
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Contacts/AcceptContactRequest": {
      "post": {
        "tags": [
          "Contacts"
        ],
        "summary": "Accepts a contact/follow request, establishing a connection between users.",
        "requestBody": {
          "description": "The unique identifier of the request to accept",
          "content": {
            "application/json": {
              "schema": {
                "type": "string"
              }
            },
            "text/json": {
              "schema": {
                "type": "string"
              }
            },
            "application/*+json": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Request accepted, users connected successfully"
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Request not found or already processed",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Contacts/RemoveContact": {
      "post": {
        "tags": [
          "Contacts"
        ],
        "summary": "Removes a contact/follower relationship.",
        "requestBody": {
          "description": "The contact ID to remove",
          "content": {
            "application/json": {
              "schema": {
                "type": "string"
              }
            },
            "text/json": {
              "schema": {
                "type": "string"
              }
            },
            "application/*+json": {
              "schema": {
                "type": "string"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact removed successfully"
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Contact not found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Locations/GetUserLocation": {
      "get": {
        "tags": [
          "Locations"
        ],
        "summary": "Retrieves the current GPS location for a specific user.",
        "parameters": [
          {
            "name": "userId",
            "in": "query",
            "description": "The unique anonymous user identifier",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Returns the user's current location",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "User location not found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Locations/GetMultipleUserLocations": {
      "get": {
        "tags": [
          "Locations"
        ],
        "parameters": [
          {
            "name": "userIds",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Locations/UpdateUserLocation": {
      "post": {
        "tags": [
          "Locations"
        ],
        "summary": "Updates the current GPS location for the authenticated user.",
        "description": "Sample request:\n\n    POST /api/HumanLocation/UpdateHumanLocation\n    Headers:\n      X-User-Id: user123\n      X-Registration-Key: abc-def-ghi\n    Body:\n    {\n      \"uid\": \"user123\",\n      \"latitude\": 37.7749,\n      \"longitude\": -122.4194,\n      \"timestamp\": \"2024-01-15T10:30:00Z\",\n      \"accuracy\": 10.5\n    }",
        "requestBody": {
          "description": "GPS location object containing latitude, longitude, timestamp, UID, and optional accuracy",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GPSLocation"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/GPSLocation"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/GPSLocation"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Location updated successfully",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Invalid location data provided",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Markers/SendLocationsMessage": {
      "post": {
        "tags": [
          "Markers"
        ],
        "summary": "Sends a location message to another user (coordinate sharing for meetups or item locations).",
        "description": "Use this endpoint to share specific GPS coordinates with contacts - perfect for:\n- Meetup point coordination\n- Sharing item locations\n- Emergency location beacons\n- Points of interest\n\nSample request:\n\n    POST /api/HumanLocation/SendLocationsMessage\n    Headers:\n      X-User-Id: user123\n      X-Registration-Key: abc-def-ghi\n    Body:\n    {\n      \"toUserId\": \"user456\",\n      \"latitude\": 37.7749,\n      \"longitude\": -122.4194,\n      \"message\": \"Meet me here!\",\n      \"timestamp\": \"2024-01-15T10:30:00Z\"\n    }",
        "requestBody": {
          "description": "Location message containing GPS coordinates, sender/receiver IDs, and optional description",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LocationMessage"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LocationMessage"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LocationMessage"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Location message sent successfully",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/LocationMessageApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationMessageApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationMessageApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Invalid location message data",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Markers/MarkLocationMessagesSeen": {
      "post": {
        "tags": [
          "Markers"
        ],
        "summary": "Marks all location messages for the authenticated user as seen/read.",
        "parameters": [
          {
            "name": "messageId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Markers/GetLocationMessages": {
      "get": {
        "tags": [
          "Markers"
        ],
        "summary": "Retrieves all unread location messages for the authenticated user.",
        "description": "Messages are marked as \"seen\" automatically when retrieved.\nLocation messages contain GPS coordinates shared by other users.",
        "responses": {
          "200": {
            "description": "Returns list of location messages (may be empty)",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/LocationMessageListApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationMessageListApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationMessageListApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Markers/SendMarkerLocation": {
      "post": {
        "tags": [
          "Markers"
        ],
        "summary": "Sends or saves a marker location for a specific user or shared group.",
        "description": "Use markers to save static locations that don't change frequently.\nUnlike human locations which update continuously, markers are fixed points.\n\nSample request:\n\n    POST /api/Markers/SendMarkerLocation\n    Headers:\n      X-User-Id: user123\n      X-Registration-Key: abc-def-ghi\n    Body:\n    {\n      \"uid\": \"user123\",\n      \"latitude\": 37.7749,\n      \"longitude\": -122.4194,\n      \"label\": \"Coffee Shop Meetup\",\n      \"description\": \"Our usual spot\",\n      \"timestamp\": \"2024-01-15T10:30:00Z\"\n    }",
        "requestBody": {
          "description": "GPS location marker with coordinates, owner ID, and optional label/description",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GPSLocation"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/GPSLocation"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/GPSLocation"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Marker location saved successfully",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocation"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocation"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocation"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Invalid marker data provided",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Markers/GetMarkers": {
      "get": {
        "tags": [
          "Markers"
        ],
        "summary": "Retrieves all markers for a specific user.",
        "responses": {
          "200": {
            "description": "Returns list of markers (may be empty)",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationListApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationListApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/GPSLocationListApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    },
    "/api/Registration/RegisterUser": {
      "post": {
        "tags": [
          "Registration"
        ],
        "summary": "Registers a new device/user or validates existing credentials. Essential first step for AI agents.",
        "description": "This is the entry point for AI agents. First call this endpoint to get authentication credentials.\n\nFor NEW users:\n- Provide a unique userId (anonymous identifier you choose)\n- Provide a deviceId (unique to your agent instance)\n- Receive registrationKey and refreshToken\n\nFor EXISTING users:\n- Provide userId, deviceId, and registrationKey\n- Validates credentials and returns tokens\n\nSample request (new registration):\n\n    POST /api/Contacts/RegisterContact\n    Body:\n    {\n      \"userId\": \"agent-bot-001\",\n      \"deviceId\": \"ai-agent-instance-xyz\"\n    }\n\nResponse:\n\n    {\n      \"success\": true,\n      \"data\": {\n        \"registrationKey\": \"abc-def-ghi-jkl\",\n        \"refreshToken\": \"refresh-xyz-123\",\n        \"expiresAt\":  \"2024-02-15T10:30:00Z\"\n      }\n    }\n\nUse the registrationKey in X-Registration-Key header and userId in X-User-Id header for all subsequent API calls.",
        "requestBody": {
          "description": "Registration data including userId and deviceId",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Registration"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/Registration"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/Registration"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Device registered successfully or existing credentials validated",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid registration data",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid credentials for existing user",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/Registration/RefreshToken": {
      "post": {
        "tags": [
          "Registration"
        ],
        "summary": "Refreshes an expired registration key using a valid refresh token.",
        "description": "Call this endpoint when your registration key expires (check expiresAt from registration response).\n\nSample request:\n\n    POST /api/Contacts/RefreshToken\n    Body:\n    {\n      \"userId\": \"agent-bot-001\",\n      \"refreshToken\": \"refresh-xyz-123\"\n    }",
        "requestBody": {
          "description": "Registration data with userId and refreshToken",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Registration"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/Registration"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/Registration"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token refreshed successfully",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request data",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              }
            }
          },
          "401": {
            "description": "Invalid or expired refresh token",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegistrationApiResponse"
                }
              }
            }
          }
        }
      }
    },
    "/api/Registration/RevokeDevice": {
      "post": {
        "tags": [
          "Registration"
        ],
        "summary": "Revokes the current device's access, invalidating all tokens.",
        "description": "Use this when decommissioning an AI agent or changing user ID.\nAfter revocation, you must re-register to get new credentials.",
        "responses": {
          "200": {
            "description": "Device revoked successfully"
          },
          "401": {
            "description": "Authentication failed - invalid or missing credentials",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "400": {
            "description": "Failed to revoke device",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ContactRequestDto": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "fromUserId": {
            "type": "string",
            "nullable": true
          },
          "fromUsername": {
            "type": "string",
            "nullable": true
          },
          "toUserId": {
            "type": "string",
            "nullable": true
          },
          "toUsername": {
            "type": "string",
            "nullable": true
          },
          "requestType": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "isIncoming": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "seen": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "GPSLocation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "uid": {
            "type": "string",
            "nullable": true
          },
          "latitude": {
            "type": "number",
            "format": "double"
          },
          "longitude": {
            "type": "number",
            "format": "double"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "accuracy": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "altitude": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "speed": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "bearing": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "battery": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "GPSLocationApiResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/GPSLocation"
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "errorCode": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "integer",
            "format": "int64"
          },
          "datatype": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "GPSLocationListApiResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GPSLocation"
            },
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "errorCode": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "integer",
            "format": "int64"
          },
          "datatype": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "LocationMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "locations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GPSLocation"
            },
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "fromUserId": {
            "type": "string",
            "nullable": true
          },
          "fromUsername": {
            "type": "string",
            "nullable": true
          },
          "toUserId": {
            "type": "string",
            "nullable": true
          },
          "toUsername": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "seen": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "LocationMessageApiResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/LocationMessage"
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "errorCode": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "integer",
            "format": "int64"
          },
          "datatype": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "LocationMessageListApiResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LocationMessage"
            },
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "errorCode": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "integer",
            "format": "int64"
          },
          "datatype": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": { }
      },
      "Registration": {
        "type": "object",
        "properties": {
          "userid": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "deviceid": {
            "type": "string",
            "nullable": true
          },
          "registrationkey": {
            "type": "string",
            "nullable": true
          },
          "refreshtoken": {
            "type": "string",
            "nullable": true
          },
          "expiresat": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "timestamp": {
            "type": "string",
            "nullable": true
          },
          "signature": {
            "type": "string",
            "nullable": true
          },
          "success": {
            "type": "boolean"
          },
          "errormessage": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RegistrationApiResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/Registration"
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "errorCode": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "integer",
            "format": "int64"
          },
          "datatype": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "DeviceAuth": {
        "type": "apiKey",
        "description": "Device authentication using X-User-Id and X-Registration-Key headers. Both headers are required for authenticated endpoints.",
        "name": "X-User-Id",
        "in": "header"
      },
      "RegistrationKey": {
        "type": "apiKey",
        "description": "Registration key paired with X-User-Id for device authentication.",
        "name": "X-Registration-Key",
        "in": "header"
      }
    }
  },
  "security": [
    {
      "DeviceAuth": [ ]
    }
  ],
  "tags": [
    {
      "name": "Contacts"
    },
    {
      "name": "Locations"
    },
    {
      "name": "Markers"
    },
    {
      "name": "Registration"
    }
  ]
}