resolveIdentifier GraphQL Mutation
Created: Tue 29 Jul 2025 08:58:00 CEST
Document Version: 1.0 - Initial API requirements
Security Classification: Internal Technical Documentation
Target Audience: Backend Developers, API Developers
Author: Paul Wisén
Overview
The resolveIdentifier mutation is a critical endpoint that the Director service (s.plings.io) calls to verify and resolve Plings identifiers into routing decisions. This endpoint performs cryptographic verification, retrieves object context, and returns routing instructions.
GraphQL Schema
input ResolveIdentifierInput {
type: String! # Tag type: 'plgs', 'mfr', etc.
identifier: String! # Full identifier (e.g., "plgs_1_12345")
classPointer: String # Optional class pointer for verification
scanMetadata: ScanMetadataInput
}
input ScanMetadataInput {
timestamp: DateTime!
ipAddress: String
userAgent: String
referer: String
geoLocation: GeoLocationInput
}
input GeoLocationInput {
latitude: Float
longitude: Float
accuracy: Float
consent: Boolean!
}
type ResolveIdentifierResponse {
success: Boolean!
routing: RoutingDecision!
object: ObjectContext
scanEvent: ScanEvent
error: ErrorResponse
}
type RoutingDecision {
action: RoutingAction! # REDIRECT, SHOW_INFO, ERROR
destination: String # URL to redirect to
parameters: [Parameter!] # Additional URL parameters
cacheTTL: Int # Cache duration in seconds
}
enum RoutingAction {
REDIRECT # Redirect to destination URL
SHOW_INFO # Show information page
ERROR # Show error page
}
type ObjectContext {
objectId: String!
status: ObjectStatus!
owner: OwnerInfo
manufacturer: ManufacturerInfo
class: ObjectClassInfo
location: LocationInfo
}
enum ObjectStatus {
ACTIVE
FOR_SALE
FOR_RENT
LOST
ARCHIVED
UNKNOWN
}
type Parameter {
key: String!
value: String!
}
Request Flow
Director (s.plings.io) → Backend API (api.plings.io)
↓
1. Extract parameters from QR scan
2. Call resolveIdentifier mutation
3. Backend performs:
- Manufacturer validation
- Cryptographic verification
- Object lookup
- Context retrieval
- Routing decision
4. Return routing instructions
5. Director redirects user
Implementation Requirements
1. Manufacturer Verification
- Validate manufacturer ID exists
- Check manufacturer status (active/suspended)
- Verify cryptographic signatures if provided
2. Object Resolution
- Look up object by identifier
- Check object status and ownership
- Retrieve current location (if tracked)
- Get associated business rules
3. Routing Logic
Based on object context, determine destination:
| Object Status | Destination | Parameters |
|---|---|---|
| FOR_SALE | market.plings.io | oid, price, seller |
| FOR_RENT | rent.plings.io | oid, rate, owner |
| LOST | plings.io/found | oid, reward, contact |
| UNKNOWN | plings.io/create | ikey, suggested_class |
| ACTIVE | plings.io/object | oid, view_mode |
4. Scan Event Logging
Every scan must be logged with:
- Timestamp
- Identifier scanned
- IP address (hashed)
- Geographic location (if consented)
- Routing decision made
- User agent
5. Performance Requirements
- Response time: <200ms (95th percentile)
- Caching: Support cache headers for routing decisions
- Rate limiting: Implement per-IP limits
Example Request
mutation ResolveIdentifier($input: ResolveIdentifierInput!) {
resolveIdentifier(input: $input) {
success
routing {
action
destination
parameters {
key
value
}
cacheTTL
}
object {
objectId
status
owner {
name
verified
}
class {
name
category
}
}
scanEvent {
id
timestamp
}
error {
code
message
}
}
}
Variables:
{
"input": {
"type": "plgs",
"identifier": "plgs_1_abc123xyz",
"classPointer": "4K7mX9abDcE",
"scanMetadata": {
"timestamp": "2025-07-29T12:00:00Z",
"ipAddress": "192.168.1.1",
"userAgent": "Mozilla/5.0...",
"geoLocation": {
"latitude": 59.3293,
"longitude": 18.0686,
"accuracy": 10.5,
"consent": true
}
}
}
}
Response Examples
Success - Known Object for Sale
{
"data": {
"resolveIdentifier": {
"success": true,
"routing": {
"action": "REDIRECT",
"destination": "https://market.plings.io/item",
"parameters": [
{ "key": "oid", "value": "obj_123abc" },
{ "key": "src", "value": "scan" },
{ "key": "ref", "value": "plgs_1_abc123xyz" }
],
"cacheTTL": 300
},
"object": {
"objectId": "obj_123abc",
"status": "FOR_SALE",
"owner": {
"name": "John's Bike Shop",
"verified": true
},
"class": {
"name": "Mountain Bike",
"category": "Sports Equipment"
}
},
"scanEvent": {
"id": "scan_789xyz",
"timestamp": "2025-07-29T12:00:00Z"
}
}
}
}
Success - Unknown Identifier
{
"data": {
"resolveIdentifier": {
"success": true,
"routing": {
"action": "REDIRECT",
"destination": "https://plings.io/create",
"parameters": [
{ "key": "ikey", "value": "plgs_999_unknown" },
{ "key": "src", "value": "scan" },
{ "key": "suggested", "value": "generic-item" }
],
"cacheTTL": 3600
},
"object": null,
"scanEvent": {
"id": "scan_456def",
"timestamp": "2025-07-29T12:00:01Z"
}
}
}
}
Error - Invalid Identifier
{
"data": {
"resolveIdentifier": {
"success": false,
"routing": {
"action": "ERROR",
"destination": "https://plings.io/error",
"parameters": [
{ "key": "code", "value": "INVALID_IDENTIFIER" }
],
"cacheTTL": 86400
},
"error": {
"code": "INVALID_IDENTIFIER",
"message": "The identifier format is invalid"
}
}
}
}
Security Considerations
- Rate Limiting: Implement per-IP rate limits (100 req/min)
- Input Validation: Strict validation of all parameters
- Authentication: Director service must authenticate with API key
- Encryption: All communication over HTTPS
- Privacy: Hash IP addresses, require consent for geolocation
Implementation Priority
- Phase 1 (MVP): Basic identifier validation and routing
- Phase 2: Full object context and status-based routing
- Phase 3: Scan analytics and geolocation features
- Phase 4: Advanced caching and performance optimization