こんにちは。AIRSでインターンをしている増田です。
社内でBasecampを使うことになりました。BasecampのAPIをさわる前に、"ドキュメント":http://www.basecamphq.com/api/ を翻訳してみました。ところどころ訳がひどいのですが公開します。
What are people doing with the API?
Mac OS Xのダッシュボードウィジェット、チケットのトラッキングシステム、バグ通知システム、Basecampのモバイルバージョン、Basecampやその他のタブレットPCバージョンが作られている。"いくつかのサンプル":http://www.basecamphq.com/extras.php を見てみよう。
Introduction
BasecampのAPIはHTTP上のvanilla XMLとして実装されている。YAMLフォーマットがお好みならそれでリクエストを送ることもできるが、レスポンスはXMLである。リクエストのコンテントタイプヘッダにはapplication/xml(YAMLのリクエストならapplication/x-yaml)をセットすること。これは送られてきたデータのフォーマットを識別する。また、BasecampがあなたにHTMLの代わりにXMLで返答できるように、Acceptヘッダもapplication/xmlにセットしなければならない。以下はCurlでの例である。
curl -H 'Accept: application/xml' -H 'Content-Type: application/xml' -d '<request>...</request>' http://url
認証はHTTP認証(今のところBasic認証だけサポートされている)を使って管理されている。すべてのリクエストは認証HTTPヘッダを含んでいなければならない。
以下はcurlを使った例である。
curl -H 'Accept: application/xml' -H 'Content-Type: application/xml' -u hoodlum:up2n0g00d -d '<request>
...
</request>' http://url
上の例では、成功するとXMLフォーマットのレスポンスが返される(さらなるインスピレーションのために"Rubyラッパー":http://www.basecamphq.com/api/basecamp.rb を見ることができる)。
リクエストが失敗すると、エラーの情報はHTTPのステータスコードで返される。例えば、要求されたレコードが見つからなかった場合、HTTPレスポンスは次のようになる。
HTTP/1.1 404 The record could not be found
Date: Thu, 16 Mar 2006 17:41:40 GMT
...
一般に、リクエストが新しいレコード(新しいメッセージ、to-doアイテム、など)を生成するようなものなら、レスポンスは201 Createdステータスになるということに注意。他の成功した操作(成功した問い合わせ、削除、更新)のステータスコードは200になるだろう。
SSL Note: SSLが有効になっているアカウントへのリクエストにはリダイレクトが返される。SSLを要求するアカウントへはhttps上で呼び出すようにすること。
以下のドキュメントでは、次の表記が使われる。
- #{text}: あなたのデータで置き換えられるテキストを示す。
- …: ドキュメントを短くするためにレスポンスの内容が省略されたことを示す。レスポンスのタイプのフォーマットの完全な記述はページの最後にあるデータレスポンスのリストを見よ。
Attaching Files via the API
メッセージやコメントの作成、既存のメッセージ・コメントの更新のようないくつかの操作はでは、レコードにファイルを添付することができる。これをAPIを通して行うために、HTTP Acceptヘッダにapplication/xmlをセットして、/uploadのURIにPOSTリクエストを送る必要がある。リクエストの本体は、添付したいファイルにするべきである。
POST /upload HTTP/1.0
Accept: application/xml
Content-Type: application/octet-stream
Content-Length: 23123
... (file contents go here)
アップロードが成功すると、アップロードファイルのIDを教えるXMLレスポンスが返るだろう。(この時点で、アップロードファイルはどんなレコードとも関連づけられていない。もしあなたが何もしなければ、30分以内に削除されるだろう)
HTTP/1.0 200 OK
Content-Type: application/xml
<?xml version="1.0" encoding="UTF-8"?>
<upload><id>441b2cec.eve.21267</id></upload>
IDを手に入れたら、次のステップはレコードにファイルを取り付けることである。create messageアクションを使うことによって、例えば一連の添付データを渡す。添付したい2つのファイル(すでに書いたように、前にアップロードしたものだ)があるとすると、添付データはXMLフォーマットではこのようになる。
<attachments>
<name>A pretty sunset</name>
<file>
<file>441b2cec.eve.21267</file>
<content-type>image/jpg</content-type>
<original-filename>sunset.jpg</original-filename>
</file>
</attachments>
<attachments>
<name>The ocean</name>
<file>
<file>441b2fff.log.21285</file>
<content-type>image/png</content-type>
<original-filename>ocean.png</original-filename>
</file>
</attachments>
あなたのために、この例はRubyラッパーが実装している。望むなら、インスピレーションのためにその実装を見ることができる。(RubyラッパーはXMLの代わりにYAMLを使っていることに注意)
General
file categories: /projects/#{project-id}/attachment_categories
これは参照されたプロジェクト内のすべてのファイルのカテゴリーのリストをアルファベット順で返す。
- Response
-
<attachment-categories> <attachment-category> ... </attachment-category> <attachment-category> ... </attachment-category> ... </attachment-categories>
message categories: /projects/#{project-id}/post_categories
これは参照されたプロジェクトのすべてのメッセージのカテゴリーのリストをアルファベット順で返す。
- Response
-
<post-categories> <post-category> ... </post-category> <post-category> ... </post-category> ... </post-categories>
projects: /project/list
これはあなたがアクセスした、アクティブ、保留、完了のすべてのプロジェクトのリストを返す。リストは順序づけられていない。
- Response
-
<projects> <project> ... </project> <project> ... </project> ... </projects>
Messages and Comments
comment: /msg/comment/#{comment_id}
指定したidのコメントを取得する。
-
Response
-
<comment> ... </comment>
comments: /msg/comments/#{message_id}
指定したメッセージと関連づけられたコメントのリストを返す。
-
Response
-
<comments> <comment> ... </comment> <comment> ... </comment> ... </comments>
create comment: /msg/create_comment
特定のメッセージと関連した新しいコメントを作成する。
-
XML request
-
<request> <comment> <post-id>#{post_id}</post-id> <body>#{body}</body> </comment> </request> -
YAML request
-
--- comment: post-id: #{post_id} body: #{body} -
Response
-
<comment> ... </comment>
create message: /projects/#{project_id}/msg/create
メッセージを作成し、任意で、選択した人に通知を送る。この機能を使ってファイルをアップロードすることもできるが、まず始めにファイルをアップロードし、それからそれらを添付する必要がある。更なる情報はこのドキュメントのトップの記述を見よ。
-
XML request
-
<request> <post> <category-id>#{category_id}</category-id> <title>#{title}</title> <body>#{body}</body> <extended-body>#{extended_body}</extended-body> <use-textile>1</use_textile> <!-- omit to not use textile --> <private>1</private> <!-- only for firm employees --> </post> <notify>#{person_id}</notify> <notify>#{person_id}</notify> ... <attachments> <name>#{name}</name> <!-- optional --> <file> <file>#{temp_id}</file> <!-- the id of the previously uploaded file --> <content-type>#{content_type}</content-type> <original_filename>#{original_filename}</original-filename> </file> </attachments> <attachments>...</attachments> ... </request> -
YAML request
-
--- post: category-id: #{category_id} title: #{title} body: #{body} extended-body: #{extended_body} use-textile: #{true|false} private: #{true|false} notify: - #{person_id} - #{person_id} ... attachments: - name: #{name} file: file: #{temp_id} content-type: #{content_type} original-filename: #{original_filename} ... -
Response
-
<post> ... </post>
delete comment: /msg/delete_comment/#{comment_id}
指定したidのコメントを削除する。
-
Response
-
<comment> ... </comment>
delete message: /msg/delete/#{message_id}
プロジェクトから特定のメッセージを削除する。
-
Response
-
<post> ... </post>
message: /msg/get/#{message_ids}
これは参照されたメッセージについての情報を返す。idがコンマ区切りのリストで与えられると、それぞれのidに対して1つのレコードが返される。この方法で、1つのリクエストでメッセージの集合を問い合わせることができる。一つのリクエストにつき最大25個のidまで与えることができ、それ以上はエラーになることに注意せよ。
-
Response
-
<posts> <post> ... </post> <post> ... </post> ... </posts>
message archive: /projects/#{project_id}/msg/archive
これはプロジェクト内のそれぞれのメッセージの概要のレコードを返す。category_idを指定すると、そのカテゴリーのメッセージだけが返される。(概要のレコードは投稿についての少しの情報のみ含んでいて完全なレコードではないことに注意せよ)
-
XML request
-
<request> <project-id>#{project_id}</project-id> <!-- optional --> <category-id>#{optional_category_id}</category-id> </request> -
YAML request
-
--- project-id: #{project_id} # optional category-id: #{optional_category_id} -
Response
-
<posts> <post> ... <!-- abbreviated post --> </post> <post> ... <!-- abbreviated post --> </post> ... </posts>
message archive per category: /projects/#{project_id}/msg/cat/#{category_id}/archive
これは特定のカテゴリーにあるそれぞれのメッセージのための概要のレコードを返す。(概要のレコードは投稿についての少しの情報のみ含んでいて完全なレコードではないことに注意せよ)
-
Response
-
<posts> <post> ... <!-- abbreviated post --> </post> <post> ... <!-- abbreviated post --> </post> ... </posts>
update comment: /msg/update_comment
特定のコメントを更新する。これは既存のコメントの内容を編集するために使うことができる。
-
XML request
-
<request> <comment_id>#{comment_id}</comment_id> <comment> <body>#{body}</body> </comment> </request> -
YAML request
-
--- comment_id: #{comment_id} comment: body: #{body} -
Response
-
<comment> ... </comment>
update message: /msg/update/#{message_id}
既存のメッセージを更新し、任意で、選んだ人に通知を送ることができる。この機能を使ってファイルをアップロードすることができるが、リクエストをmultipart/form-dataとしてフォーマットしなければならないことに注意せよ。(この使用例はRuby Basecamp APIラッパーを見よ)
-
XML request
-
<request> <post> <category-id>#{category_id}</category-id> <title>#{title}</title> <body>#{body}</body> <extended-body>#{extended_body}</extended-body> <use-textile>1</use-textile> <!-- omit to not use textile --> <private>1</private> <!-- only for firm employees --> </post> <notify>#{person_id}</notify> <notify>#{person_id}</notify> ... </request> -
YAML request
-
--- post: category-id: #{category_id} title: #{title} body: #{body} extended-body: #{extended_body} use-textile: #{true|false} private: #{true|false} notify: - #{person_id} - #{person_id} ... -
Response
-
<post> ... </post>
To-do Lists and Items
complete item: /todos/complete_item/#{id}
特定のアイテムを「完了」にする。すでにそのアイテムが完了している場合は何もしない。
-
Response
-
<todo-item> ... </todo-item>
create item: /todos/create_item/#{list_id}
この呼び出しは既存のリストにアイテムを追加する。アイテムはリストの最後に追加される。もしある人がそのアイテムに返答可能の場合、party_idの値としてそれらのidを与えよ。もしcompanyが返答可能である場合、それらのidの前にcをつけ、それをparty_idの値として使うこと。もしアイテムが返答可能partyとしてある人を持っている場合、その割当について彼らに教えるためにメールを送信するかどうかを指定するために通知キーを使うことができる。
-
XML request
-
<request> <content>#{content}</content> <!-- if the item has a responsible party --> <responsible-party>#{party_id}</responsible-party> <notify>#{true|false}</notify> <request> -
YAML request
-
--- content: #{content} # if the item has a responsible party responsible-party: #{party_id} notify: #{true|false} -
Response
-
<todo-item> ... </todo-item>
create list: /projects/#{project_id}/todos/create_list
これは新しい空のリストを作成する。リストを明確に作るか、ベースとするリストのテンプレートidを与えることによって新しいリストを作ることができる。
-
XML request
-
<request> <milestone-id>#{milestone_id}</milestone-id> <!-- optional --> <private>#{true|false}</private> <!-- optional --> <tracked>#{true|false}</tracked> <!-- enable/disable time tracking --> <!-- if created from explicit metadata --> <name>#{name}</name> <description>#{description}</description> <!-- if created by a template id --> <use-template>true</use-template> <template-id>#{template_id}</template-id> </request> -
YAML request
-
--- milestone-id: #{milestone_id} # optional private: #{true|false} # optional tracked: #{true|false} # enable/disable time tracking, optional # if created from explicit metadata name: #{name} description: #{description} # if created by a template id use-template: true template-id: #{template_id} -
Response
-
<todo-list> ... </todo-list>
delete item: /todos/delete_item/#{id}
特定のアイテムを消し、その親のリストからも削除する。
-
Response
-
<todo-item> ... </todo-item>
delete list: /todos/delete_list/#{id}
この呼び出しは参照した全体のリストと、それに関係するすべてのアイテムを削除する。削除したリストは戻すことができないので、注意して使うこと。
-
Response
-
<todo-list> ... </todo-list>
list: /todos/list/#{id}
これは特定のリストのメタデータとアイテムを返す。
-
Response
-
<todo-list> ... <todo-items> ... </todo-items> </todo-list>
lists: /projects/#{project_id}/todos/lists
これは与えられたプロジェクト内のリストのすべてのためのメタデータを返す。さらに、「完了」(完了していないアイテムを含まない)や「未完」(完了していないアイテムを残している)リストだけを返すようにクエリを抑制することができる。
-
XML request
-
<request> <complete>#{true|false}</complete> <!-- optional --> </request> -
YAML request
-
--- complete: #{true|false} # optional -
Response
-
<todo-lists> <todo-list> ... </todo-list> <todo-list> ... </todo-list> ... </todo-lists>
move item: /todos/move_item/#{id}
親のリスト内でのアイテムの位置を変更する。アイテムの親を変更することは現在サポートされていない。位置1はリストの先頭である。リストの最後を超えてアイテムを移動することで、アイテムをリストの最後に置く。
-
XML request
-
<request> <to>#{to}</to> <request> -
YAML request
-
--- to: #{to} -
Response
-
<todo-list> ... </todo-list>
move list: /todos/move_list/#{id}
これによって、リストをプロジェクト内の他のリストに対して相対的にあるリストを配置し直すことができる。位置1のリストはページのトップに現れるだろう。リストを移動することはあなたを優先させる。リストを位置1以下、またはプロジェクトのリストの数より大きい数字に移動すると、位置を1からリストの数の間にする。
-
XML request
-
<request> <to>#{to}</to> </request> -
YAML request
-
--- to: #{to} -
Response
-
<todo-list> ... </todo-list>
uncomplete item: /todos/uncomplete_item/#{id}
特定のアイテムを「未完」にする。そのアイテムがすでに未完である場合、何もしない。
-
Response
-
<todo-item> ... </todo-item>
update item: /todos/update_item/#{id}
既存のアイテムを更新する。値はcreate itemの操作のように働くので、より詳細な説明のためにはそれを参照するべきである。
-
XML request
-
<request> <item> <content>#{content}</content> </item> <!-- if the item has a responsible party --> <responsible-party>#{party_id}</responsible-party> <notify>#{true|false}</notify> <request> -
YAML request
-
--- item: content: #{content} # if the item has a responsible party responsible-party: #{party_id} notify: #{true|false} -
Response
-
<todo-item> ... </todo-item>
update list: /todos/update_list/#{id}
この呼び出しで、リストのメタデータを変更することができる。
-
XML request
-
<request> <list> <name>#{name}</name> <description>#{description}</description> <milestone-id>#{milestone_id}</milestone-id> <private>#{true|false}</private> <tracked>#{true|false}</tracked> <!-- enable/disable time tracking --> </list> <request> -
YAML request
-
--- list: name: #{name} description: #{description} milestone-id: #{milestone_id} private: #{true|false} tracked: #{true|false} -
Response
-
<todo-list> ... </todo-list>
Milestones
complete: /milestones/complete/#{id}
特定のマイルストーンを完了としてマークする。
-
Response
-
<milestone> ... </milestone>
create: /projects/#{project_id}/milestones/create
1つのマイルストーンを作成する。1回の呼び出しで複数のマイルストーンを作成するにはcreate(batch)機能を見よ。companyをマイルストーンに対して返答可能にするために、company idの先頭にcをつけよ。
-
XML request
-
<request> <milestone> <title>#{title}</title> <deadline type="date">#{deadline}</deadline> <responsible-party>#{id}</responsible-party> <notify>#{true|false}</notify> </milestone> </request> -
YAML request
-
--- milestone: title: #{title} deadline: #{deadline} responsible-party: #{responsible_party} notify: #{true|false} -
Response
-
<milestones> <milestone> ... </milestone> </milestones>
create (batch): /projects/#{project_id}/milestones/create
この機能によって、1回のリクエストで複数のマイルストーンを作成することができる。マイルストーンの個々のフィールドの記述についてはcreate機能を見よ。
-
XML request
-
<request> <milestone> <title>#{title}</title> <deadline>#{deadline}</deadline> <responsible-party>#{id}</responsible-party> <notify>#{true|false}</notify> </milestone> <milestone> <title>#{title}</title> <deadline>#{deadline}</deadline> <responsible-party>#{id}</responsible-party> <notify>#{true|false}</notify> </milestone> ... </request> -
YAML request
-
--- milestone: - title: #{title} deadline: #{deadline} responsible-party: #{responsible_party} notify: #{true|false} - title: #{title} deadline: #{deadline} responsible-party: #{responsible_party} notify: #{true|false} ... -
Response
-
<milestones> <milestone> ... </milestone> <milestone> ... </milestone> ... </milestones>
delete: /milestones/delete/#{id}
プロジェクトから指定されたマイルストーンを削除する。
-
Response
-
<milestone> ... </milestone>
list: /projects/#{project_id}/milestones/list
これはプロジェクトのマイルストーンのリストを問い合わせる。すべてのマイルストーンを返させたり、最新のもの、完了したもの、近づいているもののみを返させたりすることができる。
-
XML request
-
<request> <!-- optional, defaults to all --> <find>#{all|late|completed|upcoming}</find> </request> -
YAML request
-
--- find: #{all|late|completed|upcoming} -
Response
-
<milestones> <milestone> ... </milestone> <milestone> ... </milestone> ... </milestones>
uncomplete: /milestones/uncomplete/#{id}
特定のマイルストーンを未完としてマークする。
-
Response
-
<milestone> ... </milestone>
update: /milestones/update/#{id}
1つのマイルストーンを更新する。1つのマイルストーンのデッドラインを移動したり、任意で後ろのマイルストーンのデッドラインを移動することさえできる。
-
XML request
-
<request> <milestone> <title>#{title}</title> <deadline>#{deadline}</deadline> <responsible-party>#{responsible_party}</responsible-party> <notify>#{true|false}</notify> </milestone> <move-upcoming-milestones>#{true|false}</move-upcoming-milestones> <move-upcoming-milestones-off-weekends>#{true|false}</move-upcoming-milestones-off-weekends> </request> -
YAML request
-
--- milestone: title: #{title} deadline: #{deadline} responsible-party: #{responsible_party} notify: #{true|false} move-upcoming-milestones: #{true|false} move-upcoming-milestones-off-weekends: #{true|false} -
Response
-
<milestone> ... </milestone>
Time Tracking
create: /time/save_entry
このメソッドにより、特定の人とプロジェクトの新しいタイムエントリを作ることができる。成功すると201のステータスコードを返す。
-
XML request
-
<request> <entry> <project-id>#{project_id}</project-id> <person-id>#{person-id}</person-id> <date>#{date}</date> <hours>#{hours}</hours> <!-- if not associated with a todo-item --> <description>#{description}</description> <!-- if associated with a todo-item --> <todo-item-id>#{todo-item-id}</todo-item-id> </entry> </request> -
YAML request
-
--- entry: project-id: #{project-id} person-id: #{person-id} date: #{date} hours: #{hours} description: #{description} todo-item-id: #{todo-item-id} -
Response
-
<time-entry> ... </time-entry>
delete: /projects/#{project_id}/time/delete_entry/#{id}
特定のタイムエントリを削除する。
-
Response
-
<time-entry> ... </time-entry>
report: /time/report/#{person-id}/#{from}/#{to}/#{filter}
このメソッドで、様々な方法によってタイムエントリを問い合わせることができる。peron-idによって問い合わせたくないなら、URL中のその位置に0を置くこと。fromとtoも同様である(デフォルトのfrom/toの値が使われる)。90日以上のデータを問い合わせることができるケースはない。filterパラメータは空白か、pで始まるidナンバー(特定のプロジェクトで絞り込む)、cで始まるidナンバー(特定のcompanyで絞り込む)である。言い換えると、/time/report/5/20060101/20060207/c7は、idが5の人で、idが7のcompanyに関連するすべてのプロジェクトに対して、2006-01-01から2006-02-07の間のすべてのタイムエントリを返すだろう。
-
XML request
-
<request> </request> -
YAML request
-
--- -
Response
-
<time-entries> <time-entry> ... </time-entry> <time-entry> ... </time-entry> ... </time-entries>
update: /time/save_entry/#{id}
このメソッドによって、特定のタイムエントリを更新することができる。
-
XML request
-
<request> <entry> <project-id>#{project_id}</project-id> <person-id>#{person-id}</person-id> <date>#{date}</date> <hours>#{hours}</hours> <!-- if not associated with a todo-item --> <description>#{description}</description> <!-- if associated with a todo-item --> <todo-item-id>#{todo-item-id}</todo-item-id> </entry> </request> -
YAML request
-
--- entry: project-id: #{project-id} person-id: #{person-id} date: #{date} hours: #{hours} description: #{description} todo-item-id: #{todo-item-id} -
Response
-
<time-entry> ... </time-entry>
Contact Management
companies: /contacts/companies
指定された人が見ることのできるすべてのcompanyのリストを返す。これはfirm(アカウントと関連づけられたcompany)の従業員にだけアクセスが許されている。クライアントの従業員がこのメソッドにアクセスすると、403のレスポンスが返る。
-
Response
-
<companies> <company> ... </company> ... </companies>
company: /contacts/company/#{company_id}
これは参照されたcompanyの情報を返す。
-
Response
-
<company> ... </company>
people: /contacts/people/#{company_id}
これは与えられたcompany内のすべての人を返す。プロジェクトidが与えられると、与えられたプロジェクトにアクセスすることができる人たちだけに絞り込む。
-
Response
-
<people> <person> ... </person> <person> ... </person> ... </people>
people per project: /projects/#{project_id}/contacts/people/#{company_id}
これは、指定されたcompony内の、プロジェクトにアクセすることができるすべての人を返す。
-
Response
-
<people> <person> ... </person> <person> ... </person> ... </people>
person: /contacts/person/#{person_id}
これは参照された人の情報を返す。
-
Response
-
<person> ... </person>
Data Reference
以下のセクションでは、APIのレスポンスで使われる様々なデータのタイプのフォーマットを記述している。
abbreviated post
<post>
<id type="integer">#{id}</id>
<title>#{title}</title>
<posted-on type="datetime">#{posted_on}</posted-on>
<attachments-count type="integer">#{attachments_count}</attachments-count>
<category>
<id type="integer">#{id}</id>
<name>#{name}</name>
</category>
</post>
comment
<comment id="#{id}">
<post_id>#{post_id}</post_id>
<creator_name>#{creator_name}</creator_name>
<creator_id>#{creator_id}</creator_id>
<body>#{body}</body>
<posted_on>#{posted_on}</posted_on>
</comment>
company
<company>
<id type="integer">#{id}</id>
<name>#{name}</name>
<address-one>#{address_one}</address-one>
<address-two>#{address_two}</address-two>
<city>#{city}</city>
<state>#{state}</state>
<zip>#{zip}</zip>
<country>#{country}</country>
<web-address>#{web_address}</web-address>
<phone-number-office>#{phone_number_office></phone-number-office>
<phone-number-fax>#{phone_number_fax}</phone-number-fax>
<time-zone-id>#{time_zone_id}</time-zone-id>
<can-see-private type="boolean">#{can_see_private}</can-see-private>
<!-- for non-client companies -->
<url-name>#{url_name}</url-name>
</company>
file category
<attachment-category>
<id type="integer">#{id}</id>
<name>#{name}</name>
<project-id type="integer">#{project_id}</project-id>
<elements-count type="integer">#{elements_count}</elements-count>
</attachment-category>
message category
<post-category>
<id type="integer">#{id}</id>
<name>#{name}</name>
<project-id type="integer">#{project_id}</project-id>
<elements-count type="integer">#{elements_count}</elements-count>
</post-category>
milestone
<milestone>
<id type="integer">#{id}</id>
<title>#{title}</title>
<deadline type="date">#{deadline}</deadline>
<completed type="boolean">#{true|false}</completed>
<project-id type="integer">#{project_id}</project-id>
<created-on type="datetime">#{created_on}</created-on>
<creator-id type="integer">#{creator_id}</creator-id>
<responsible-party-id type="integer">#{responsible_party_id}</responsible-party-id>
<responsible-party-type>#{responsible_party_type}</responsible-party-type>
<!-- if the milestone has been completed -->
<completed-on type="datetime">#{completed_on}</completed-on>
<completer-id type="integer">#{completer_id}</completer-id>
</milestone>
person
<person>
<id type="integer">#{id}</id>
<first-name>#{first_name}</first-name>
<last-name>#{last_name}</last-name>
<title>#{title}</title>
<email-address>#{email_address}</email-address}
<im-handle>#{im_handle}</im-handle>
<im-service>#{im_service}</im-service>
<phone-number-office>#{phone_number_office}</phone-number-office>
<phone-number-office-ext>#{phone_number_office_ext}</phone-number-office-ext>
<phone-number-mobile>#{phone_number_mobile}</phone-number-mobile>
<phone-number-home>#{phone_number_home}</phone-number-home>
<phone-number-fax>#{phone_number_fax}</phone-number-fax>
<last-login type="datetime">#{last_login}</last-login>
<client-id type="integer">#{client_id}</client-id>
<!-- if user is an administrator, or is self -->
<user-name>#{user_name}</user-name>
<!-- if user is self -->
<password>#{password}</password>
<token>#{token}</token>
<!-- if user is an administrator -->
<administrator type="boolean">#{administrator}</administrator>
<deleted type="boolean">#{deleted}</deleted>
<has-access-to-new-projects type="boolean">#{has_access_to_new_projects}</has-access-to-new-projects>
</person>
post
<post>
<id type="integer">#{id}</id>
<title>#{title}</title>
<body>#{body}</body>
<posted-on type="datetime">#{posted_on}</posted-on>
<project-id type="integer">#{project_id}</project-id>
<category-id type="integer">#{category_id}</category-id>
<author-id type="integer">#{author_id}</author-id>
<milestone-id type="integer">#{milestone_id}</milestone-id>
<comments-count type="integer">#{comments_count}</comments-count>
<attachments-count type="integer">#{attachments_count}</attachments-count>
<use-textile type="boolean">#{use_textile}</use-textile>
<extended-body>#{extended_body}</extended-body>
<display-body>#{display_body}</display-body>
<display-extended-body>#{display_extended_body}</display-extended-body>
<!-- if user can see private posts -->
<private type="boolean">#{private}</private>
</post>
project
<project>
<id type="integer">#{id}</id>
<name>#{name}</name>
<created-on type="datetime">#{created_on}</created-on>
<status>#{status}</status>
<last-changed-on type="datetiem">#{last_changed_on}</last-changed-on>
<company>
<id type="integer">#{id}</id>
<name>#{name}</name>
</company>
<!-- if user is administrator, or show_announcement is true -->
<announcement>#{announcement}</announcement>
<!-- if user is administrator -->
<start-page>#{start_page}</start-page>
<show-writeboards type="boolean">#{show_writeboards}</show-writeboards>
<show-announcement type="boolean">#{show_announcement}</show-announcement>
</project>
time entry
<time-entry>
<id type="integer">#{id}</id>
<project-id type="integer">#{project-id}</project-id>
<person-id type="integer">#{person-id}</person-id>
<date type="date">#{date}</date>
<hours>#{hours}</hours>
<description>#{description}</description>
<todo-item-id type="integer">#{todo-item-id}</todo-item-id>
</time-entry>
todo item
<todo-item>
<id type="integer">#{id}</id>
<content>#{content}</content>
<position type="integer">#{position}</position>
<created-on type="datetime">#{created_on}</created-on>
<creator-id type="integer">#{creator_id}</creator-id>
<completed type="boolean">#{completed}</completed>
<!-- if the item has a responsible party -->
<responsible-party-type>#{responsible_party_type}</responsible-party-type>
<responsible-party-id type="integer">#{responsible_party_id}</responsible-party-id>
<!-- if the item has been completed -->
<completed-on type="datetime">#{completed_on}</completed-on>
<completer-id type="integer">#{completer_id}</completer-id>
</todo-item>
todo list
<todo-list>
<id type="integer">#{id}</id>
<name>#{name}</name>
<description>#{description}</description>
<project-id type="integer">#{project_id}</project-id>
<milestone-id type="integer">#{milestone_id}</milestone-id>
<position type="integer">#{position}</position>
<!-- if user can see private lists -->
<private type="boolean">#{private}</private>
<!-- if todo-items are included in the response -->
<todo-items>
<todo-item>
...
</todo-item>
<todo-item>
...
</todo-item>
...
</todo-items>
</todo-list>