-
Notifications
You must be signed in to change notification settings - Fork 0
ThingData Protocol Specification
Version 1.0.0 - December 2024
ThingData is an open protocol for documenting and sharing repair knowledge. Its primary aims are to:
- Extend the lifetime of goods and materials
- Make repair knowledge accessible and verifiable
- Support local adaptation of repair methods
- Track environmental and social impact of repairs
- Support category-based documentation and knowledge sharing
- Enable community-driven knowledge sharing
- All repair knowledge should be freely accessible
- Multiple perspectives should be preserved
- Local adaptations should be encouraged
- Community knowledge is valuable
- No single point of control
- Federation between instances
- Community governance
- Local autonomy
- Promote repair over replacement
- Track environmental impact
- Enable knowledge reuse across similar items
- Document resource efficiency
- Support circular economy
- Multiple languages supported
- Various knowledge systems respected
- Different repair approaches validated
- Local contexts considered
ThingData operates through three core entities that work together to create a comprehensive repair knowledge ecosystem:
Physical objects and their variations across:
- Time (versions, generations)
- Space (geographical variants)
- Function (adaptations, modifications)
- Context (use cases, environments)
- Categories (types and classifications)
Real-world experiences of:
- Repairs
- Maintenance
- Modifications
- Transformations
- Adaptations
- Part replacements
- General repair procedures
- Category-based repairs
Structured knowledge resources:
- Service documentation
- Manufacturer manuals
- Video tutorials
- Technical and component specifications
- Repair procedures
- Maintenance schedules
- Transformation tutorials
- Tool requirements
- Safety guidelines
- Category-based guidance
- Community discussions
- Educational materials
- Repair databases
Guides can include external resources, in which case the following elements can be included:
- Original source location
- Internet Archive backup
- Content verification
- Access requirements
- Usage context
- Format details
{
"id": "UUID",
"created_at": "datetime",
"updated_at": "datetime",
"data": {
"name": {
"default": "string",
"translations": {"lang_code": "string"}
},
"manufacturer": {
"name": "string",
"website": {
"primary": "string",
"archive": {
"wayback": "string?",
"archived_date": "ISO8601?",
"status": "enum(AVAILABLE|PENDING|FAILED)"
}
},
"contact": "string?"
},
"model": {
"name": "string",
"number": "string?",
"series": "string?",
"year": "number?",
"generation": "string?",
"variations": [{
"market": "string",
"identifier": "string",
"differences": ["string"]
}]
},
"physical_properties": {
"dimensions": {
"length": {"value": "number", "unit": "string"},
"width": {"value": "number", "unit": "string"},
"height": {"value": "number", "unit": "string"}
},
"weight": {
"value": "number",
"unit": "string"
},
"materials": [{
"name": "string",
"type": "string",
"recyclable": "boolean",
"hazardous": "boolean"
}]
},
"sustainability": {
"repairability_score": "number?",
"lifetime_expectancy": "string?",
"energy_rating": "string?",
"certifications": [{
"name": "string",
"issuer": "string",
"date": "ISO8601"
}]
}
}
}{
"id": "UUID",
"thing_id": "UUID?",
"thing_category": {
"category": "string",
"subcategory": "string?",
"attributes": {
"key": "value"
}
},
"created_at": "datetime",
"updated_at": "datetime",
"data": {
"type": ["repair"|"maintenance"|"modification"|"diagnosis"],
"version": {
"number": "string",
"parent_uri": "URI?",
"date": "ISO8601",
"history": [{
"version": "string",
"date": "ISO8601",
"changes": ["string"],
"author_uri": "URI"
}]
},
"author": {
"uri": "URI",
"name": "string",
"instance_uri": "URI",
"expertise": ["string"],
"certifications": ["string"]
},
"metadata": {
"title": {
"default": "string",
"translations": {"lang_code": "string"}
},
"description": {
"default": "string",
"translations": {"lang_code": "string"}
},
"difficulty": "enum(EASY|MEDIUM|HARD|EXPERT)",
"time_estimate": {
"duration": "number",
"unit": "string",
"skill_factor": "string?"
},
"cost_estimate": {
"amount": "number",
"currency": "string",
"region": "string?",
"date": "ISO8601"
}
},
"prerequisites": {
"skills": [{
"name": "string",
"level": "enum(BASIC|INTERMEDIATE|ADVANCED)",
"description": "string"
}],
"tools": [{
"thing_uri": "URI",
"required": "boolean",
"alternatives": ["URI"]
}],
"parts": [{
"thing_uri": "URI",
"quantity": "number",
"required": "boolean",
"alternatives": ["URI"]
}],
"safety": {
"warnings": ["string"],
"equipment": ["URI"],
"certifications_needed": ["string"]
}
},
"procedure": {
"steps": [{
"order": "number",
"title": {
"default": "string",
"translations": {"lang_code": "string"}
},
"description": {
"default": "string",
"translations": {"lang_code": "string"}
},
"warnings": ["string"],
"media": [{
"uri": "URI",
"type": "string",
"caption": "string",
"timestamp": "string?",
"archive": {
"wayback": "string?",
"archived_date": "ISO8601?",
"status": "enum(AVAILABLE|PENDING|FAILED)",
"local_cache": "URI?"
}
}],
"duration": {
"estimate": "number",
"unit": "string"
},
"tools_used": ["URI"],
"parts_used": ["URI"],
"verification": {
"checks": ["string"],
"success_indicators": ["string"]
}
}]
}
}
}{
"id": "UUID",
"thing_id": "UUID?",
"thing_category": {
"category": "string",
"subcategory": "string?",
"attributes": {
"key": "value"
}
},
"created_at": "datetime",
"updated_at": "datetime",
"data": {
"type": {
"primary": ["manual"|"tutorial"|"specification"|"documentation"],
"secondary": ["repair"|"maintenance"|"transformation"|"safety"]
},
"title": {
"default": "string",
"translations": {"lang_code": "string"}
},
"source": {
"type": ["manufacturer"|"community"|"professional"|"regulatory"],
"url": {
"primary": "string",
"archive": {
"wayback": "string?",
"archived_date": "ISO8601?",
"status": "enum(AVAILABLE|PENDING|FAILED)",
"local_cache": "URI?"
}
},
"platform": "string?",
"author": "string?",
"publication_date": "datetime?",
"license": "string?"
},
"content": {
"summary": {
"default": "string",
"translations": {"lang_code": "string"}
},
"requirements": {
"skills": ["string"],
"tools": ["string"],
"materials": ["string"],
"certifications": ["string"]
},
"warnings": [{
"default": "string",
"translations": {"lang_code": "string"},
"severity": "enum(INFO|CAUTION|WARNING|DANGER)"
}]
}
}
}{
"id": "UUID",
"source_type": "enum(thing|guide|story)",
"source_id": "UUID",
"target_type": "enum(thing|guide|story)",
"target_id": "UUID",
"relationship_type": "string",
"direction": "enum(unidirectional|bidirectional)",
"metadata": {
"description": {
"default": "string",
"translations": {"lang_code": "string"}
},
"properties": {
"key": "value"
},
"context": {
"key": "value"
},
"validity": {
"from": "ISO8601?",
"until": "ISO8601?"
}
},
"created_at": "datetime",
"updated_at": "datetime"
}{
"id": "guide:repair/laptop/hinge",
"thing_category": {
"category": "laptop",
"subcategory": "notebook",
"attributes": {
"form_factor": "clamshell",
"size_range": "13-15 inch"
}
},
"data": {
"type": {
"primary": "guide",
"secondary": "repair"
},
"title": {
"default": "Universal Laptop Hinge Repair Guide",
"translations": {
"de": "Universelle Reparaturanleitung für Laptop-Scharniere"
}
},
"content": {
"summary": {
"default": "General guidance for repairing laptop hinges across various models"
},
"requirements": {
"skills": ["Basic electronics", "Screwdriver usage"],
"tools": ["Screwdriver set", "Plastic pry tools"],
"materials": ["Replacement hinges", "Screws"]
},
"warnings": [
{
"severity": "CAUTION",
"default": "Disconnect battery before starting"
}
]
},
"external_content": [
{
"type": "video",
"url": {
"primary": "https://example.com/video-tutorial",
"archive": {
"wayback": "https://web.archive.org/web/20240327/example.com/video-tutorial",
"archived_date": "2024-03-27",
"status": "AVAILABLE",
"local_cache": "local://cache/video-123"
}
},
"format": "mp4",
"language": "en",
"access_requirements": {
"requires_registration": false,
"requires_payment": false,
"region_restricted": false
},
"verification": {
"last_checked": "2024-03-27T12:00:00Z",
"checksum": "sha256:abc123...",
"verified": true
}
}
]
}
}{
"id": "guide:manual/fairphone/fp5-repair",
"thing_id": "thing:device/fairphone/fp5/eu",
"data": {
"type": {
"primary": "external",
"secondary": "repair"
},
"title": {
"default": "Fairphone 5 Repair Manual"
},
"source": {
"type": "manufacturer",
"author": "Fairphone",
"publication_date": "2023-09-01"
},
"external_content": {
"type": "document",
"url": {
"primary": "https://support.fairphone.com/fp5-repair-manual",
"archive": {
"wayback": "https://web.archive.org/web/20240327/support.fairphone.com/fp5-repair-manual",
"archived_date": "2024-03-27",
"status": "AVAILABLE",
"local_cache": "local://cache/manual-456"
}
},
"format": "pdf",
"language": "en",
"access_requirements": {
"requires_registration": false,
"requires_payment": false,
"region_restricted": false
},
"verification": {
"last_checked": "2024-03-27T12:00:00Z",
"checksum": "sha256:def456...",
"verified": true
}
}
}
}{
"instance": {
"id": "URI",
"name": "string",
"type": ["repair_cafe"|"manufacturer"|"community"|"research"|"regulatory"],
"profile": {
"description": "string",
"location": {
"city": "string",
"country": "string",
"coordinates": [number, number]
},
"specializations": ["string"],
"languages": ["string"]
},
"technical": {
"version": "string",
"capabilities": ["string"],
"endpoints": {
"webfinger": "URL",
"api": "URL",
"federation": "URL"
},
"public_key": "string"
}
}
}{
"federation": {
"discovery": {
"protocol": "webfinger",
"lookup": "/.well-known/webfinger"
},
"sync": {
"protocol": "activitypub",
"activities": [
"Create",
"Update",
"Delete",
"Verify",
"Dispute",
"Resolve"
]
},
"validation": {
"signatures": true,
"consensus_required": ["safety", "regulatory"],
"local_override": true
},
"archival": {
"external_content": {
"archive_on_ingest": true,
"verify_periodically": true,
"backup_frequency": "7d",
"storage_policy": {
"local_cache": true,
"max_size": "100MB",
"allowed_formats": ["pdf", "html", "txt", "jpg", "png", "mp4"]
}
},
"sharing": {
"cache_sharing": true,
"max_share_size": "50MB",
"require_verification": true
}
}
}
}{
"sync_request": {
"id": "UUID",
"source_instance": "URI",
"target_instance": "URI",
"content_type": ["thing"|"story"|"guide"],
"content_id": "UUID",
"include_external": true,
"external_content_policy": {
"sync_cache": true,
"verify_links": true,
"update_archives": true
},
"context": {
"language": ["string"],
"region": "string?",
"categories": ["string"],
"verification_required": "boolean"
}
}
}{
"trust": {
"levels": {
"verified": "Cryptographically signed content",
"consensus": "Community-verified content",
"reported": "Content with warnings",
"untrusted": "New or disputed content"
},
"verification": {
"methods": ["signature", "consensus", "authority"],
"thresholds": {
"consensus": {
"minimum_verifications": 3,
"timeframe": "72h"
}
},
"external_content": {
"url_verification": true,
"content_integrity": true,
"archive_verification": true,
"periodic_recheck": "7d"
}
},
"delegation": {
"trust_chains": true,
"max_depth": 3,
"require_direct_verification": ["safety"]
}
}
}# Things
GET /api/v1/things
POST /api/v1/things
GET /api/v1/things/{id}
PUT /api/v1/things/{id}
DELETE /api/v1/things/{id}
# Stories
GET /api/v1/stories
POST /api/v1/stories
GET /api/v1/stories/{id}
PUT /api/v1/stories/{id}
DELETE /api/v1/stories/{id}
# Guides
GET /api/v1/guides
POST /api/v1/guides
GET /api/v1/guides/{id}
PUT /api/v1/guides/{id}
DELETE /api/v1/guides/{id}
GET /api/v1/guides/{id}/external-content
GET /api/v1/guides/{id}/archive
# Relationships
GET /api/v1/relationships
POST /api/v1/relationships
GET /api/v1/relationships/{id}
PUT /api/v1/relationships/{id}
DELETE /api/v1/relationships/{id}
Query Parameters for Guides:
- category: string
- type: enum(manual|tutorial|specification|external)
- has_external_content: boolean
- verified_only: boolean
- include_archive: boolean
GET /.well-known/webfinger
GET /api/v1/federation/discover
POST /api/v1/federation/sync
GET /api/v1/federation/status
{
"technical_requirements": {
"data_storage": {
"persistence": {
"database": "PostgreSQL 15+",
"json_support": "JSONB required",
"full_text_search": true,
"content_archival": {
"local_cache": true,
"backup_support": true
}
},
"backup": {
"frequency": "daily",
"retention": "90d",
"encryption": true
}
},
"api": {
"rest": {
"required": true,
"openapi": "3.0+",
"documentation": true
},
"relationships": {
"bidirectional": true,
"cross_entity": true,
"category_support": true
},
"external_content": {
"url_validation": true,
"archive_integration": true,
"content_verification": true
}
},
"security": {
"authentication": true,
"authorization": true,
"encryption": {
"in_transit": true,
"at_rest": true
}
}
}
}- All forms of repair knowledge are valuable
- Multiple valid approaches can coexist
- Local expertise is respected
- Community consensus over central authority
- Safety information supersedes other concerns
- Mandatory safety reviews for critical repairs
- Clear warning systems
- Rapid safety update propagation
{
"governance": {
"levels": {
"local": {
"scope": "instance",
"autonomy": ["content", "moderation", "policies"],
"responsibilities": [
"content_creation",
"local_verification",
"community_management",
"dispute_resolution"
]
},
"regional": {
"scope": "geographic_cluster",
"focus": [
"regional_standards",
"local_regulations",
"resource_availability",
"cultural_practices"
]
},
"federation": {
"scope": "network",
"responsibilities": [
"protocol_development",
"safety_standards",
"interoperability",
"conflict_resolution"
]
}
},
"councils": {
"technical": {
"scope": "protocol_development",
"election": "merit_based",
"term": "1y"
},
"safety": {
"scope": "safety_standards",
"election": "expertise_based",
"term": "2y"
},
"community": {
"scope": "governance",
"election": "community_vote",
"term": "1y"
}
}
}
}{
"content_governance": {
"external_content": {
"verification": {
"initial_check": {
"url_validation": true,
"content_accessibility": true,
"format_verification": true
},
"periodic_check": {
"frequency": "7d",
"verify_availability": true,
"update_archive": true
}
},
"preservation": {
"local_cache": {
"required": true,
"update_on_change": true
},
"internet_archive": {
"required": true,
"submit_if_missing": true
}
}
},
"moderation": {
"grounds": [
"safety",
"accuracy",
"spam",
"copyright",
"accessibility"
],
"appeal_process": true,
"transparency_required": true
}
}
}{
"conflict_resolution": {
"process": {
"levels": [
"automated",
"community",
"council",
"federation"
],
"escalation_criteria": ["string"],
"timeframes": {
"initial_response": "24h",
"community_review": "7d",
"council_decision": "14d",
"federation_resolution": "30d"
}
},
"external_content_conflicts": {
"source_unavailable": {
"action": "switch_to_archive",
"notification_required": true
},
"content_changed": {
"action": "version_conflict",
"preserve_original": true,
"update_archive": true
},
"access_requirements_changed": {
"action": "review_accessibility",
"find_alternatives": true
}
}
}
}{
"versioning": {
"protocol": {
"version": "1.0.0",
"reference_implementation": "0.1.3",
"features": {
"required": [
"Thing management",
"Story management",
"Guide management with external content support",
"Flexible relationships",
"Category-based documentation"
],
"optional": [
"Federation",
"Advanced search",
"Content archival"
]
}
}
}
}- All implementations must support Things, Stories, and Guides
- Guide implementations must handle both native and external content
- Relationship system must support all entity types
- Category-based documentation must be supported
- External content handling must include verification and archival capabilities
- Federation capabilities
- Advanced search functionality
- Local content caching
- Automated archival
- Impact tracking
- Entities must maintain backward compatibility
- Optional fields can be added in minor versions
- Required fields can only be added in major versions
- Field deprecation requires one minor version notice
- Relationship model changes require major version bump
The reference implementation (ThingData Server) demonstrates:
- Core data models implementation
- API endpoints
- Relationship management
- Category-based documentation
- Multi-language support
Current features in reference implementation v0.1.3:
- Complete Thing, Story, and Guide CRUD operations
- Flexible relationship system between all entities
- Category-based documentation support
- Bidirectional relationships
- Enhanced metadata support
- Cross-entity relationship querying
- Federation protocol implementation
- Advanced search capabilities
- File attachment support
- Media management
- Impact tracking
- Analytics system
- Protocol v1.x maintains backward compatibility
- Data models remain stable within major versions
- API endpoints support versioned responses
- Relationship model supports future extensions
- Category system allows hierarchical expansion
- Protocol Wiki Page: https://github.com/reuse-city/thingdata-server/wiki/ThingData-Protocol-Specification
- Reference Implementation: https://github.com/reuse-city/thingdata-server
This protocol specification is licensed under the Apache License, Version 2.0 (the "License"); you may not use this documentation except in compliance with the License.
You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
The License ensures that the protocol specification remains open while providing patent protection and encouraging wide adoption. The choice of Apache 2.0 reflects our commitment to:
- Keeping the protocol specification freely available
- Protecting implementers through patent grants
- Encouraging commercial and non-commercial adoption
- Maintaining compatibility with implementations under other licenses
Note that while this protocol specification is under Apache 2.0, the reference implementation (ThingData Server) is licensed under AGPL-3.0.
End of ThingData Protocol Specification v1.0