openapi: 3.0.3 info: title: Badger Maps API description: >- REST API for Badger Maps, field sales route-planning and CRM software. The API lets teams programmatically manage accounts (customers), account locations, optimized routes, check-ins (served under the /appointments/ resource), and users. Base URL: https://badgerapis.badgermapping.com/api/2. All requests are authenticated with a token supplied in an `Authorization: Token ` header. API/Developer Key access is included with paid plans (max 25k requests per day, per team); the key must be enabled by contacting Badger Maps support (support@badgermapping.com). Endpoint paths, methods, and the core request/response fields below are grounded in Badger Maps' published API Blueprint (Apiary). Fields marked "modeled" in descriptions are reasonable inferences where the public docs are thin and require an enabled key to verify exhaustively. version: '2.0' contact: name: Badger Maps Support url: https://support.badgermapping.com email: support@badgermapping.com servers: - url: https://badgerapis.badgermapping.com/api/2 description: Badger Maps API v2 security: - tokenAuth: [] tags: - name: Users description: Authentication, the authenticated user profile, and user search. - name: Accounts description: Accounts (customers) - the businesses and contacts a rep maps and visits. - name: Locations description: Physical, geocoded locations attached to an account. - name: Check-Ins description: Timestamped activity logs recorded against an account (the /appointments/ resource). - name: Routes description: Optimized driving routes and their ordered waypoints. paths: /login/: post: operationId: login tags: - Users summary: Authenticate and obtain an API token description: >- Exchanges a username and password for an API token that is then sent in the `Authorization: Token ` header on subsequent requests. requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object required: - username - password properties: username: type: string password: type: string format: password responses: '200': description: Authentication succeeded; returns the token and user id. content: application/json: schema: $ref: '#/components/schemas/AuthResponse' '401': $ref: '#/components/responses/Unauthorized' /profiles/: get: operationId: getProfile tags: - Users summary: Retrieve the authenticated user profile description: >- Returns the profile of the authenticated user, including company info, profile settings, and the account custom data-field schema (datafields). responses: '200': description: The authenticated user's profile. content: application/json: schema: $ref: '#/components/schemas/Profile' '401': $ref: '#/components/responses/Unauthorized' /search/users/: get: operationId: searchUsers tags: - Users summary: Search for users description: >- Searches users the authenticated account manages, by email or user ID. parameters: - name: q in: query required: true description: Query string - an email address or user ID. schema: type: string responses: '200': description: Matching users. content: application/json: schema: type: array items: $ref: '#/components/schemas/User' '401': $ref: '#/components/responses/Unauthorized' /customers/: get: operationId: listAccounts tags: - Accounts summary: List accounts description: >- Returns an array of accounts (customers) owned by the authenticated user. The optional `rn` parameter (modeled) scopes the list to a managed user. parameters: - name: rn in: query required: false description: Optional managed-user id to scope the list to (modeled). schema: type: integer responses: '200': description: A list of accounts. content: application/json: schema: type: array items: $ref: '#/components/schemas/Account' '401': $ref: '#/components/responses/Unauthorized' post: operationId: createAccount tags: - Accounts summary: Create an account description: >- Creates a new account (customer). Requires at least a name and address plus an account owner; latitude/longitude and custom data fields are optional. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AccountInput' responses: '201': description: The created account. content: application/json: schema: $ref: '#/components/schemas/Account' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /customers/{account_id}/: parameters: - $ref: '#/components/parameters/AccountId' get: operationId: getAccount tags: - Accounts summary: Retrieve an account description: Returns a single account with its locations and custom fields. responses: '200': description: The requested account. content: application/json: schema: $ref: '#/components/schemas/Account' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' patch: operationId: updateAccount tags: - Accounts summary: Update an account description: >- Partially updates an account - for example custom_text fields or a change of account_owner. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/AccountInput' responses: '200': description: The updated account. content: application/json: schema: $ref: '#/components/schemas/Account' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' delete: operationId: deleteAccount tags: - Accounts summary: Delete an account description: Deletes an account (customer). Returns 204 No Content on success. responses: '204': description: The account was deleted. '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /locations/{location_id}/: parameters: - $ref: '#/components/parameters/LocationId' patch: operationId: updateLocation tags: - Locations summary: Update an account location description: >- Updates a location attached to an account. An address is required; latitude/longitude may be supplied to override Badger's geocoding. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/LocationInput' responses: '200': description: The updated location. content: application/json: schema: $ref: '#/components/schemas/Location' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /appointments/: get: operationId: listCheckIns tags: - Check-Ins summary: List check-ins description: >- Returns the check-ins recorded against an account. Filter by account with the `customer_id` query parameter. parameters: - name: customer_id in: query required: false description: The account (customer) id to return check-ins for. schema: type: integer responses: '200': description: A list of check-ins. content: application/json: schema: type: array items: $ref: '#/components/schemas/CheckIn' '401': $ref: '#/components/responses/Unauthorized' post: operationId: createCheckIn tags: - Check-Ins summary: Create a check-in description: >- Records a new check-in against an account. Requires the account (customer) id; a type and free-text comments are optional. requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CheckInInput' responses: '201': description: The created check-in. content: application/json: schema: $ref: '#/components/schemas/CheckIn' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /routes/: get: operationId: listRoutes tags: - Routes summary: List routes description: Returns the authenticated user's routes (id, name, and route date). responses: '200': description: A list of routes. content: application/json: schema: type: array items: $ref: '#/components/schemas/RouteSummary' '401': $ref: '#/components/responses/Unauthorized' /routes/{route_id}/: parameters: - $ref: '#/components/parameters/RouteId' get: operationId: getRoute tags: - Routes summary: Retrieve a route description: >- Returns a single route with its ordered waypoints. Each waypoint references an account location, its position in the sequence, and timing details. responses: '200': description: The requested route. content: application/json: schema: $ref: '#/components/schemas/Route' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' components: securitySchemes: tokenAuth: type: apiKey in: header name: Authorization description: >- Token authentication. Send `Authorization: Token `. Contact Badger Maps support to have your API/Developer Key enabled. parameters: AccountId: name: account_id in: path required: true description: The account (customer) id. schema: type: integer LocationId: name: location_id in: path required: true description: The location id. schema: type: integer RouteId: name: route_id in: path required: true description: The route id. schema: type: integer responses: Unauthorized: description: Authentication is missing or the token is invalid. content: application/json: schema: $ref: '#/components/schemas/Error' NotFound: description: The requested resource was not found. content: application/json: schema: $ref: '#/components/schemas/Error' BadRequest: description: The request was invalid or missing required fields. content: application/json: schema: $ref: '#/components/schemas/Error' schemas: AuthResponse: type: object properties: token: type: string description: API token to send in the Authorization header. status: type: string user_id: type: integer Profile: type: object properties: id: type: integer username: type: string first_name: type: string last_name: type: string email: type: string format: email company: type: object description: Company the user belongs to. additionalProperties: true datafields: type: array description: Custom data-field schema configured for accounts. items: type: object additionalProperties: true settings: type: object description: Profile settings (modeled). additionalProperties: true User: type: object properties: id: type: integer username: type: string first_name: type: string email: type: string format: email Account: type: object properties: id: type: integer first_name: type: string last_name: type: string email: type: string format: email phone_number: type: string account_owner: type: integer description: User id of the account owner. external_id: type: string description: Identifier of the account in an external system (e.g. CRM). locations: type: array items: $ref: '#/components/schemas/Location' custom_text: type: object description: Custom text data fields configured on the account. additionalProperties: true AccountInput: type: object required: - last_name - address - account_owner properties: last_name: type: string first_name: type: string address: type: string email: type: string format: email phone_number: type: string account_owner: type: integer lat: type: number format: float lng: type: number format: float custom_text: type: object additionalProperties: true Location: type: object properties: id: type: integer address: type: string lat: type: number format: float lng: type: number format: float LocationInput: type: object required: - address properties: address: type: string lat: type: number format: float lng: type: number format: float CheckIn: type: object description: A check-in log against an account (served under /appointments/). properties: id: type: integer customer: type: integer description: The account (customer) id the check-in belongs to. type: type: string description: Check-in type. comments: type: string log_datetime: type: string format: date-time created_by: type: integer description: User id of the check-in author. CheckInInput: type: object required: - customer properties: customer: type: integer description: The account (customer) id to log the check-in against. type: type: string comments: type: string RouteSummary: type: object properties: id: type: integer name: type: string route_date: type: string format: date Route: allOf: - $ref: '#/components/schemas/RouteSummary' - type: object properties: waypoints: type: array items: $ref: '#/components/schemas/Waypoint' Waypoint: type: object properties: position: type: integer description: Order of this stop in the route. customer_id: type: integer location: $ref: '#/components/schemas/Location' start_time: type: string description: Planned arrival/timing detail (modeled). duration: type: integer description: Planned stop duration in minutes (modeled). Error: type: object properties: detail: type: string status: type: integer